Copepod Collection

Copepods were collected at approximately weekly intervals from Lake Champlain (Burlington Fishing Pier). Plankton was collected from the top 3 meters using a 250 um mesh net.

# # Lake Champlain near Burlington, VT
# siteNumber = "04294500"
# ChamplainInfo = readNWISsite(siteNumber)
# parameterCd = "00010"
# startDate = "2023-01-01"
# endDate = "2024-5-20"
# #statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean
# 
# # Constructs the URL for the data wanted then downloads the data
# url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd,
#                        startDate = startDate, endDate = endDate, service = "uv")
# 
# raw_temps = importWaterML1(url, asDateTime = T) %>%
#   mutate("date" = as.Date(dateTime),
#          "hour" = hour(dateTime)) %>%
#   select(dateTime, tz_cd, date, hour, degC = X_00010_00000)
# 
# temp_data =  raw_temps %>%
#   select(date, hour, "temp" = degC)
# 
# write.csv(temp_data, file = "./Output/Data/champlain_temps.csv", row.names = F)

Collections began in late May 2023. Several gaps are present, but collections have continued at roughly weekly intervals since then. Copepods from 48 collections were used to make a total of 1312 thermal limit measurements. Over this time period, collection temperatures ranged from 2.5 to 26.5°C.

There is substantial variation in thermal limits across the species collected. There is also some degree of variation within the species, with thermal limits increasing slightly during the summer.

## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
  ungroup() %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            med_temp = median(temp),
            var_temp = var(temp), 
            min_temp = min(temp), 
            max_temp = max(temp)) %>% 
  mutate("range_temp" = max_temp - min_temp,
         date = as.Date(date)) %>% 
  ungroup() %>%  
  filter(date >= (min(as.Date(full_data$collection_date)) - 7)) %>% 
  left_join(unique(select(full_data, collection_date, collection_temp)), by = join_by(date == collection_date))

## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%  
  #filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))

adult_summaries = full_data %>%  
  filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))


tseries_data = full_data %>% 
  mutate(sp_name = fct_reorder(sp_name, ctmax, .desc = T))

ggplot() + 
  geom_vline(data = unique(select(tseries_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date),
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) +
  # geom_point(data = adult_summaries, 
  #            aes(x = as.Date(collection_date), y = mean_ctmax, colour = sp_name, size = sample_size)) + 
  geom_point(data = tseries_data, 
             aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
             size = 2, position = position_jitter(width = 1, height = 0)) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")


lake_temps = ggplot() + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 1) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")

Temperatures observed at the time of collection closely resembled the maximum daily temperature from the temperature sensor data. Maximum temperature was used as a proxy instead of mean temperature as collections were usually made during afternoons or early evenings, just following the warmest part of the day.

collection_conditions %>% 
  drop_na(collection_temp) %>%  
  ggplot(aes(x = max_temp, y = collection_temp)) + 
  geom_abline(intercept = 0, slope = 1,
              linewidth = 1, colour = "grey") + 
  geom_point(size = 3) +
  scale_x_continuous(breaks = c(5,15,25)) + 
  scale_y_continuous(breaks = c(5,15,25)) + 
  labs(x = "Max. Temp. from Sensor (°C)",
       y = "Collection Temp. (°C)") + 
  theme_matt()

Size also varied, but primarily between rather than within species.

ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date), 
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) + 
  geom_point(data = adult_summaries, 
             aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name, size = sample_size),
             position = position_dodge(width = 1)) + 
  scale_colour_manual(values = species_cols) + 
  scale_y_continuous(
    name = "Temperature", # Features of the first axis
    sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
    breaks = c(0,5,10,15,20,25,30)
  ) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species") + 
  theme_matt() + 
  theme(legend.position = "right")

sample_dates_plot = full_data %>%  
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax)) %>% 
  ggplot(aes(x = lubridate::as_date(collection_date), 
             y = sp_name, fill = sp_name)) + 
  # geom_vline(xintercept = as_date(
  #   c("2023-05-01",
  #     "2023-09-01",
  #     "2024-01-01",
  #     "2024-05-01")),
  #   colour = "grey",
  #   linewidth = 1) + 
  geom_density_ridges(bandwidth = 30,
                      jittered_points = TRUE, 
                      point_shape = 21,
                      point_size = 1,
                      point_colour = "grey30",
                      point_alpha = 0.6,
                      alpha = 0.9,
                      position = position_points_jitter(
                        height = 0.1, width = 0)) + 
  scale_fill_manual(values = species_cols) + 
  scale_x_date(date_breaks = "3 months",
               date_labels = "%b") + 
  coord_cartesian(xlim = lubridate::as_date(c("2023-04-25", "2024-06-01"))) + 
  labs(x = "Day of Year", 
       y = "Species") + 
  theme_matt() + 
  #theme_ridges(grid = T) + 
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))

The samples captured the broad seasonal changes in calanoid copepod community composition in the lake. We note, however, that rare species (e.g. Senecella and Limnocalanus) were often preferentially sampled, so are over-represented in the data set.

adult_summaries %>% 
  ungroup() %>% 
  mutate(collection_num = as.numeric(factor(collection_date))) %>% 
  group_by(collection_date) %>%  
  arrange(collection_date) %>% 
  select(sp_name, collection_date, collection_num, sample_size) %>% 
  mutate(sample_size = replace_na(sample_size, 0)) %>% 
  mutate(total = sum(sample_size),
         percentage = sample_size / total,
         collection_date = lubridate::as_date(collection_date)) %>% 
  ggplot(aes(x = collection_date, y = percentage, fill = sp_name)) + 
  geom_area() + 
  scale_fill_manual(values = species_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Species") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

Throughout the season, the prevalence of various unidentified pathogens also varied, with very little infection observed during the Winter and Spring.

pathogen_cols = c("no" = "grey95", "cloudy" = "honeydew3", "spot" = "antiquewhite3", "other" = "tomato3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by() %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  count(pathogen) %>% 
  filter(pathogen != "uncertain") %>% 
  pivot_wider(id_cols = "collection_date", 
              names_from = pathogen, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, cloudy, spot, other)) %>% 
  pivot_longer(cols = c(no, cloudy, spot, other),
               names_to = "pathogen", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         pathogen = fct_relevel(pathogen, "no", "cloudy", "spot", "other")) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = pathogen)) + 
  geom_area() + 
  scale_fill_manual(values = pathogen_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Pathogen") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The transparent bodies of these copepods also allowed us to examine seasonal patterns in lipid reserves and in the production of eggs. Maturing oocytes are visible in female copepods before they are released. There was no strong seasonal cycle in the production of these eggs in any species, and instead, females were reproductively active throughout their respective seasons of occurence.

dev_eggs_cols = c("no" = "grey95", "yes" = "lightblue3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(dev_eggs) %>% 
  filter(dev_eggs != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = dev_eggs, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "dev_eggs", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         dev_eggs = fct_relevel(dev_eggs, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, dev_eggs), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & dev_eggs == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = dev_eggs)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = dev_eggs_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Developing \nEggs") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The presence of lipids varied across species, with only L. minutus, L. sicilis, and Limnocalanus regularly possessing lipid stores.

lipid_cols = c("no" = "grey95", "yes" = "sienna2")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(lipids) %>% 
  filter(lipids != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = lipids, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "lipids", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         lipids = fct_relevel(lipids, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, lipids), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & lipids == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = lipids)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = lipid_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Lipids\nPresent") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

Temperature Variability

Lake Champlain is highly seasonal, with both average temperatures and temperature variability changing throughout the year. These patterns in the experienced thermal environment may drive the observed variation in copepod thermal limits. However, the time period affecting copepod thermal limits is unknown. Depending the on the duration of time considered, there are large changes in the experienced environment, in particular regarding the temperature range and variance. Consider for example three time periods: the day of collection, one week prior to collection, and four weeks prior to collection. While the overall pattern is similar, we can see that, unsurprisingly, considering longer periods of time results in larger ranges and slightly changes the pattern of variance experienced.

## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
  prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
  
  mean_values = daily_values %>% 
    ungroup() %>% 
    mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
           mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
           mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>% 
    select(date, mean_max, mean_min, mean_range) %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
  
  period_values = raw_temp %>% 
    mutate(mean = slide_index_mean(temp, i = date, before = days(n_days), 
                                   na_rm = T),
           max = slide_index_max(temp, i = date, before = days(n_days), 
                                 na_rm = T),
           min = slide_index_min(temp, i = date, before = days(n_days),
                                 na_rm = T),
           med = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 na_rm = T, .f = median),
           var = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 .f = var),
           range = max - min) %>%  
    select(-temp) %>%  
    distinct() %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>% 
    inner_join(mean_values, by = c("date")) %>%  
    drop_na()
  
  return(period_values)
}

Trait Variation

Shown below are the clutch size distributions for the three diaptomiid species, which produce egg sacs that allow for easy quantification of fecundity.

full_data %>%  
  drop_na(fecundity) %>%  
  ggplot(aes(x = fecundity, fill = sp_name_sub)) + 
  facet_wrap(.~sp_name_sub, ncol = 1) + 
  geom_histogram(binwidth = 2) + 
  scale_fill_manual(values = species_cols) + 
  labs(x = "Fecundity (# Eggs)") +
  theme_matt_facets() + 
  theme(legend.position = "none")

One of the main aims of this project is to examine the patterns and processes driving variation in upper thermal limits across these species of copepods.

Variation with temperature

We expect one of the primary drivers of copepod thermal limits to be temperature. The correlation analysis has shown that the copepods are generally (although not always) responding to the recent thermal environment. Shown below are thermal limits, body size, and fecundity values plotted against the temperature at the time of collection. Also shown is warming tolerance, calculated as the difference between upper thermal limit and the collection temperature.

We generally see an increase in thermal limits with increasing collection temperature, a slight decrease in body size, and variable relationships between temperature and fecundity. All species maintained some degree of buffer between environmental temperatures and upper thermal limits, but Epischura and L. minutus approached their upper thermal limits during the warmest collections during the summer.

ctmax_temp = ggplot(full_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) +   
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

size_temp = ggplot(filter(full_data, sex != "juvenile"), aes(x = collection_temp, y = size, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Length (mm)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

wt_temp = ggplot(full_data, aes(x = collection_temp, y = warming_tol, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Warming Tolerance (°C)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

eggs_temp = ggplot(full_data, aes(x = collection_temp, y = fecundity, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Fecundity (# Eggs)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(wt_temp, eggs_temp, 
          common.legend = T, legend = "right")

sp_ctmax_temp = full_data %>% 
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax, .desc = T)) %>% 
  ggplot(aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 2, alpha = 0.2) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")
ggarrange(sample_dates_plot, sp_ctmax_temp, nrow = 1, 
          labels = "AUTO")

Temperature dependence is relatively weak in L. sicilis, especially at cooler temperatures. We will return to this feature later in the report, but for now we will note that there are two size morphs in this species, which appear to respond differently to decreases in temperature. There are significant differences between the morphs and how temperature affects CTmax.

morph_data = full_data %>% 
  filter(sex == "female" & species == "leptodiaptomus_sicilis") %>%  mutate(sp_name = case_when(
    sp_name == "Leptodiaptomus sicilis" & size >= 0.89 ~ "Large",
    sp_name == "Leptodiaptomus sicilis" & size < 0.89 ~ "Small",
    .default = sp_name
  ))


ggplot(morph_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  geom_point(size = 2, alpha = 0.8) + 
  geom_smooth(method = "lm", se = T, linewidth = 2) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax (°C)") + 
  theme_matt() + 
  theme(legend.position = "none")


morph.model = lm(data = morph_data, 
                 ctmax ~ collection_temp * sp_name)

knitr::kable(car::Anova(morph.model, type = "III", test = "F"))
Sum Sq Df F value Pr(>F)
(Intercept) 11838.75134 1 3930.374601 0.0000000
collection_temp 107.57172 1 35.712986 0.0000000
sp_name 32.96638 1 10.944584 0.0010357
collection_temp:sp_name 15.88294 1 5.273014 0.0222454
Residuals 1060.26547 352 NA NA

#summary(morph.model)

morph.em = emmeans::emtrends(morph.model, "sp_name", var = "collection_temp")

knitr::kable(pairs(morph.em))
contrast estimate SE df t.ratio p.value
Large - Small 0.1530629 0.0666562 352 2.296304 0.0222454

Copepods spent several days in lab during experiments. Shown below are the CTmax residuals (taken from a model of CTmax against collection temperature) plotted against the time spent in lab before measurements were made. Individual regressions are shown for the residuals against days in lab for each collection. We can see clearly that thermal limits are fairly stable over time.

ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name, group = collection_date)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 4, alpha = 0.5) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  #scale_x_continuous(breaks = c(0:5)) + 
  labs(x = "Days in lab", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt_facets() + 
  theme(legend.position = "none")

full.model = lme4::lmer(data = model_data,
                        ctmax ~ sex + temp_cent + 
                          (1 + days_in_lab + temp_cent|sp_name))

car::Anova(full.model)
## Analysis of Deviance Table (Type II Wald chisquare tests)
## 
## Response: ctmax
##            Chisq Df Pr(>Chisq)    
## sex       50.305  2  1.193e-11 ***
## temp_cent 26.662  1  2.423e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

fixed = fixef(full.model)

model_coefs = coefficients(full.model)$`sp_name` %>%  
  rownames_to_column(var = "species") %>% 
  separate(species, into = c("species"), sep = ":") %>% 
  select(species, "intercept" = "(Intercept)", temp_cent, days_in_lab)

ggplot(model_coefs, aes(x = intercept, y = temp_cent)) + 
  geom_smooth(method = "lm", colour = "black") +
  geom_point(aes(colour = species),
             size = 6) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Species Intercept", 
       y = "ARR") +
  theme_matt() + 
  theme(legend.position = "right")

arr_combined = synth_arr %>%
  filter(measure == "upper" & mean_lim > 20) %>% 
  select("group" = genus, arr, mean_lim) %>% 
  mutate("dataset" = "synthesis") %>% 
  bind_rows(
    select(model_coefs, "group" = species, 'arr' = temp_cent, 'mean_lim' = intercept)
  ) %>% 
  mutate(dataset = if_else(is.na(dataset), "new data", "synthesis"),
         group = fct_reorder(group, arr, .desc = T))


ggplot(arr_combined, aes(x = mean_lim, y = arr)) + 
  geom_smooth(method = "lm", se = F, 
              linewidth = 2, colour = "grey30") + 
  geom_point(data = filter(arr_combined, dataset != "new data"), 
             size = 4, colour = "grey") + 
  geom_point(data = filter(arr_combined, dataset == "new data"),
             aes(colour = group), 
             size = 4) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Thermal Limit", 
       y = "ARR", 
       colour = "Species") +
  theme_matt() + 
  theme(legend.position = "right")

The term “acclimation response ratio” is often used to describe the effect of temperature on thermal limits. The ARR is calculated as the change in thermal limits per degree change in acclimation temperature. For our data, we will estimate ARR as the slope of CTmax against collection temperature. These slopes were taken from a regression of CTmax against collection temperature and body size. Two different model types were used, a simple linear regression and a mixed effects model. The estimated ARR values were generally highly similar between the model types used.

Sex and stage variation in thermal limits

Previous sections have generally lumped juvenile, female, and male individuals together. There may be important stage- or sex-specific differences in CTmax though. For several species, we have measurements for individuals in different stages or of different sexes.

sex_sample_sizes = ctmax_resids %>%  
  group_by(sp_name, sex) %>%  
  summarise(num = n()) %>%  
  pivot_wider(id_cols = sp_name,
              names_from = sex, 
              values_from = num,
              values_fill = 0) %>% 
  select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)

knitr::kable(sex_sample_sizes, align = "c")
Species Juvenile Female Male
Epischura lacustris 37 45 20
Leptodiaptomus minutus 12 273 38
Leptodiaptomus sicilis 31 356 95
Limnocalanus macrurus 4 43 39
Osphranticum labronectum 0 1 0
Senecella calanoides 13 21 8
Skistodiaptomus oregonensis 15 231 28

The female-male and female-juvenile comparisons show that there are generally no differences in thermal limits between these groups.

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Male > 0, Female > 0)$Species & 
           sex != "juvenile") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 2) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Juvenile > 0 & Female > 0)$Species & 
           sex != "male") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 2) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

Trait Correlations and Trade-offs

A relationship between size and upper thermal limits has been suggested in a wide range of other taxa. Shown below are the measured upper thermal limits plotted against prosome length. The overall relationship (inclusive of all species) is shown as the black line in the background. Regressions for each individual species are also shown. Across the entire assemblage, there is a strong decrease in thermal limits with increasing size.


full_data %>% 
  #filter(sex == "female") %>%  
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
    geom_point(size = 2, alpha = 0.3) + 
  geom_smooth(data = full_data, 
              aes(x = size, y = ctmax),
              method = "lm", 
              colour ="black", 
              linewidth = 2.5) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship for each species individually.

full_data %>% 
  #filter(sex == "female") %>%  
  group_by(sp_name) %>% filter(n() >2) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>% 
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~., scales = "free", nrow = 2) + 
  geom_point(size = 2, alpha = 0.8) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

Shown below is the relationship between mean size and mean thermal limits for females of each species. We see that larger species within the community tend to have a lower thermal limit than smaller species.

full_data %>% 
  group_by(sp_name, sex) %>% 
  summarize(mean_ctmax = mean(ctmax, na.rm = T),
            mean_size = mean(size, na.rm = T)) %>% 
  #filter(sex == "female") %>% 
  ggplot(aes(x = mean_size, y = mean_ctmax)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2, colour = "black") + 
  geom_point(aes(colour = sp_name, shape = sex),
             size = 5) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship between fecundity and size, showing the classic pattern of increasing egg production with increasing size.

size_fecund_plot = ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = size, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "Prosome length (mm)", 
       y = "Fecundity (# Eggs)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Individuals may also allocate energy to different fitness related traits, prioritizing reproductive output over environmental tolerance, for example. Shown below is the relationship between CTmax residuals (again, controlling for the effects of collection temperature) against fecundity. We can see clearly that individuals with increased fecundity are not decreasing thermal limits, suggesting that there is no energetic trade-off between these traits.

ctmax_fecund_plot = ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = resids, y = fecundity_resids, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "CTmax Residuals", 
       y = "Fecundity Residuals",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(size_fecund_plot, ctmax_fecund_plot, ncol = 1, common.legend = T, legend = "right")

Other patterns in variation

Leptodiaptomus sicilis is the most abundant species during the winter. There was a large shift in the size of mature females towards the end of December. These large and small individuals are the same species (confirmed via COI sequencing), suggesting this shift may reflect a transition from one generation to another and that, unlike in many other lakes, there are two generations of L. sicilis per year in Lake Champlain. This size difference may be caused by differences in the developmental environments. For example, individuals developing in January grow up at very low temperatures, and therefore may reach larger sizes. These individuals oversummer in deep waters, then re-emerge in October and produce a new generation. Water temperatures are still fairly high through November, which results in a generation of smaller individuals, which mature in time to produce a new generation in January.

Shown below is the distribution of pairwise distances between COI sequences of large and small morphs. Distances in both within- and across-morph comparisons are small.

ind_dist = ape::dist.dna(sic_dnabin, model = "raw") %>% as.matrix %>% 
  as_tibble() %>%
  mutate("ind1" = colnames(.)) %>% 
  pivot_longer(-ind1, names_to = "ind2", values_to = "dist") %>%
  mutate(ind1 = factor(ind1),
         ind2 = factor(ind2)) %>% 
  filter(!(ind1 == "sore1" | ind2 == "sore1")) %>% 
  mutate(
    ind1 = case_when(
      ind1 == "S1" ~ "small1",
      ind1 == "S3" ~ "small3",
      ind1 == "lsic3" ~ "small4",
      ind1 == "lsic5" ~ "small6",
      ind1 == "lsic9" ~ "small8",
      ind1 == "lsic10" ~ "small9",
      ind1 == "lsic11" ~ "small10",
      ind1 == "L1" ~ "large1",
      ind1 == "L2" ~ "large2",
      ind1 == "L3" ~ "large3",
      ind1 == "lsic1" ~ "large4",
      ind1 == "lsic2" ~ "large5",
      ind1 == "lsic7" ~ "large6",
      ind1 == "lsic8" ~ "large7"),
    ind2 = case_when(
      ind2 == "S1" ~ "small1",
      ind2 == "S3" ~ "small3",
      ind2 == "lsic3" ~ "small4",
      ind2 == "lsic5" ~ "small6",
      ind2 == "lsic9" ~ "small8",
      ind2 == "lsic10" ~ "small9",
      ind2 == "lsic11" ~ "small10",
      ind2 == "L1" ~ "large1",
      ind2 == "L2" ~ "large2",
      ind2 == "L3" ~ "large3",
      ind2 == "lsic1" ~ "large4",
      ind2 == "lsic2" ~ "large5",
      ind2 == "lsic7" ~ "large6",
      ind2 == "lsic8" ~ "large7"),
    'comparison' = case_when(
      str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "large") ~ "within",
      str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "small") ~ "within", 
      str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "small") ~ "across",
      str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "large") ~ "across"
    )) 

ggplot(ind_dist, aes(dist, fill = comparison)) +
  geom_histogram(binwidth = 0.005) + 
  labs(x = "Distance") + 
  theme_matt()

full_data %>%  
  filter(sp_name == "Leptodiaptomus sicilis") %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  mutate(size_center = scale(size, center = T, scale = F)) %>% 
  ggplot(aes(y = factor(collection_date), x = size, fill = collection_temp)) + 
  facet_wrap(sex~.) + 
  geom_density_ridges(bandwidth = 0.04) + 
  geom_vline(xintercept = 0.89) + 
  labs(x = "Size (mm)",
       y = "Date", 
       fill = "Coll. Temp. (°C)") + 
  theme_matt() + 
  theme(legend.position = "right",
        axis.text.y = element_text(size = 12))

Distribution Lag Non-Linear Model (DLNM approach)

Distributed lag models examine a response variable, measured at multiple time points, as a function of the lagged occurrence of some predictor variable (response y at time t as a function of preditor x(t-lag). This method utilizes a bi-dimensional dose-lag-response function, which essentially examines not only the dose effect, but the effect of the timing of the dose.

# Run this code, save the product, and then just read in the temp lag data object. Takes too long to run each time this document is knit. 

# lag_temps = temp_data %>%
#   group_by(date, hour) %>%
#   summarize("mean_temp" = mean(temp, na.rm = T)) %>%
#   ungroup() %>%
#   mutate(point_num = row_number())
# 
# uniq_days = length(unique(lag_temps$date))
# 
# g = gam(mean_temp ~ s(point_num, bs="cr", k=uniq_days + 10),
#     method = "REML",
#     data = lag_temps)
# 
# points = seq(1, nrow(lag_temps), length.out = length(lag_temps$hour))
# 
# df.res = df.residual(g)
# 
# pred_temps = predict(g, newdata = lag_temps, type = "response", se.fit = TRUE)
# 
# lag_temps = lag_temps %>%
#   mutate(trend_T = pred_temps$fit,
#          trend_se = pred_temps$se.fit,
#          temp_diff = mean_temp - trend_T)
# 
# write.csv(lag_temps, file = "./Output/Data/lag_temps.csv", row.names = F)

dlnm_data = full_data %>%  
  filter(sex == "female") %>% 
  filter(sp_name %in% c(
    "Leptodiaptomus sicilis",
    "Leptodiaptomus minutus",
    "Skistodiaptomus oregonensis"
  )) %>% 
  select(collection_date, collection_temp, sp_name, ctmax) %>% 
  group_by(collection_date, collection_temp, sp_name) %>%  
  summarise(mean_ctmax = mean(ctmax, na.rm = T),
            sample = n())

temp_data %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            max_temp = max(temp, na.rm = T)) %>% 
  right_join(dlnm_data, by = join_by("date" == "collection_date")) %>% 
  ggplot(aes(x = max_temp, y = mean_ctmax)) + 
  facet_wrap(.~sp_name) + 
  geom_smooth(method = "gam") + 
  geom_point() + 
  labs(x = "Max Daily Temp. (°C)",
       y = "Mean CTmax (°C)") + 
theme_matt_facets() + 
  theme(strip.text.x = element_text(size = 12))


sp_list = unique(dlnm_data$sp_name)

for(lag_species in sp_list){
  
  dlnm_data_sp = dlnm_data %>% 
    filter(sp_name == lag_species)
  
  # We need to estimate a matrix of exposure histories for each observation. This contains the series of exposures at each lag (l) for each of the n observations, constrained between l0 (minimum lag) and L (max lag). 

dates = dlnm_data_sp$collection_date # For each of these dates, make a vector of the past 30 days (including the day of collection). NOTE: Don't use 'unique' dates here since some collections had multiple species

exp_hist_z = data.frame()
exp_hist_trend = data.frame()

for(d in dates){
  
  history = lag_temps %>% 
    filter(date <= d & date > d - 10) %>% 
    arrange(desc(date), desc(hour)) %>% 
    mutate(lag = row_number() - 1) %>% 
    select(lag, mean_temp, temp_diff)
  
  z_vec = scale(history$mean_temp)[,1]
  names(z_vec) = history$lag
  
  trend_vec = history$temp_diff
  names(trend_vec) = history$lag

  exp_hist_z = bind_rows(exp_hist_z, z_vec)
  exp_hist_trend = bind_rows(exp_hist_trend, trend_vec)
  
}

#print(max(exp_hist_trend, na.rm = T))

# The cross-basis function from dlnm will use the class of the x parameter to determine what to do. In our case, we need to provide it with the matrix of exposure histories for reach observation (row) and lag (column). 

cb_temps = crossbasis(exp_hist_trend, lag = c(0,dim(exp_hist_trend)[2]-1), 
                      argvar =list(fun="cr",df=3), 
                      arglag=list(fun="cr",df=3,intercept=T))

#summary(cb_temps)

penalized_mat <- cbPen(cb_temps)

#fitting GAM
lag.gam = gam(data = dlnm_data_sp, 
              mean_ctmax ~ cb_temps + collection_temp, 
              method = "GCV.Cp",
              paraPen=list(cb_temps=penalized_mat))

# summary(lag.gam)
# AIC(lag.gam)

#estimation of exposures effects

#default plots
pred_gam_Zs<-crosspred(cb_temps, lag.gam, 
                       cumul=F, cen=0, ci.level = 0.95,
                       at=seq(-4,4, 0.1))

plot(pred_gam_Zs, "contour")
# 
# plot(pred_gam_Zs, border = 2, cumul=F,
#       theta=110,phi=20,ltheta=-80)

plot(pred_gam_Zs, "slices",
     var = c(3,-3),
     lag = c(1,200),
     col = 2)

}

if(predict_vuln == F){
  knitr::knit_exit()
}
LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9Cgp0aGVtZV9tYXR0X2ZhY2V0cyA9IGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgdGhlbWVfYncoYmFzZV9mYW1pbHk9InNhbnMiKSAlK3JlcGxhY2UlIAogICAgdGhlbWUoCiAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIHBhbmVsLmJhY2tncm91bmQgID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUpLAogICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkYXJrX3RleHQpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG1pZF90ZXh0KSwKICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMywgMCwgMCwgMCksICJtbSIpKSwKICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMCwgNSwgMCwgMCksICJtbSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlID0gOTApLAogICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPWJhc2Vfc2l6ZSAqIDAuOSksCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMC45LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIpLAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLjI1LCAwLjI1LCAwLjI1LCAwLjI1LCJjbSIpCiAgICApCn0KCnNwZWNpZXNfY29scyA9IGMoIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMiID0gIiNmZmQwMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBtaW51dHVzIGp1dmVuaWxlIiA9ICIjZTNkOGFmIiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBtYWxlIiA9ICIjZmZlODk2IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIgPSAiI0Q4NkYyOSIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMgbWFsZSIgPSAiI0UyOEMwMCIsCiAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyIgPSAiI0M1QzM1QSIsCiAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyBtYWxlIiA9ICIjZTZlNmFhIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMganV2ZW5pbGUiID0gInBsdW0xIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMgbWFsZSIgPSAicGx1bTMiLCAKICAgICAgICAgICAgICAgICAiRXBpc2NodXJhIGxhY3VzdHJpcyIgPSAicGx1bTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIiA9ICJza3libHVlNCIsIAogICAgICAgICAgICAgICAgICJMaW1ub2NhbGFudXMgbWFjcnVydXMgbWFsZSIgPSAic2t5Ymx1ZTMiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIGp1dmVuaWxlIiA9ICJza3libHVlIiwgCiAgICAgICAgICAgICAgICAgIlNlbmVjZWxsYSBjYWxhbm9pZGVzIiA9ICJkYXJrc2VhZ3JlZW4zIiwKICAgICAgICAgICAgICAgICAiTGVwdG9kb3JhIGtpbmR0aSBtYWxlIiA9ICJsaWdodGJsdWUzIiwKICAgICAgICAgICAgICAgICAiTGVwdG9kb3JhIGtpbmR0aSIgPSAibGlnaHRibHVlNCIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkganV2ZW5pbGUiID0gImxpZ2h0Ymx1ZSIsCiAgICAgICAgICAgICAgICAgIk9zcGhyYW50aWN1bSBsYWJyb25lY3R1bSIgPSAibGlnaHRjb3JhbCIpCmBgYAoKIyMgQ29wZXBvZCBDb2xsZWN0aW9uCgpDb3BlcG9kcyB3ZXJlIGNvbGxlY3RlZCBhdCBhcHByb3hpbWF0ZWx5IHdlZWtseSBpbnRlcnZhbHMgZnJvbSBMYWtlIENoYW1wbGFpbiAoQnVybGluZ3RvbiBGaXNoaW5nIFBpZXIpLiBQbGFua3RvbiB3YXMgY29sbGVjdGVkIGZyb20gdGhlIHRvcCAzIG1ldGVycyB1c2luZyBhIDI1MCB1bSBtZXNoIG5ldC4gCgpgYGB7cn0KIyAjIExha2UgQ2hhbXBsYWluIG5lYXIgQnVybGluZ3RvbiwgVlQKIyBzaXRlTnVtYmVyID0gIjA0Mjk0NTAwIgojIENoYW1wbGFpbkluZm8gPSByZWFkTldJU3NpdGUoc2l0ZU51bWJlcikKIyBwYXJhbWV0ZXJDZCA9ICIwMDAxMCIKIyBzdGFydERhdGUgPSAiMjAyMy0wMS0wMSIKIyBlbmREYXRlID0gIjIwMjQtNS0yMCIKIyAjc3RhdENkID0gYygiMDAwMDEiLCAiMDAwMDIiLCIwMDAwMyIsICIwMDAxMSIpICMgMSAtIG1heCwgMiAtIG1pbiwgMyA9IG1lYW4KIyAKIyAjIENvbnN0cnVjdHMgdGhlIFVSTCBmb3IgdGhlIGRhdGEgd2FudGVkIHRoZW4gZG93bmxvYWRzIHRoZSBkYXRhCiMgdXJsID0gY29uc3RydWN0TldJU1VSTChzaXRlTnVtYmVycyA9IHNpdGVOdW1iZXIsIHBhcmFtZXRlckNkID0gcGFyYW1ldGVyQ2QsCiMgICAgICAgICAgICAgICAgICAgICAgICBzdGFydERhdGUgPSBzdGFydERhdGUsIGVuZERhdGUgPSBlbmREYXRlLCBzZXJ2aWNlID0gInV2IikKIyAKIyByYXdfdGVtcHMgPSBpbXBvcnRXYXRlck1MMSh1cmwsIGFzRGF0ZVRpbWUgPSBUKSAlPiUKIyAgIG11dGF0ZSgiZGF0ZSIgPSBhcy5EYXRlKGRhdGVUaW1lKSwKIyAgICAgICAgICAiaG91ciIgPSBob3VyKGRhdGVUaW1lKSkgJT4lCiMgICBzZWxlY3QoZGF0ZVRpbWUsIHR6X2NkLCBkYXRlLCBob3VyLCBkZWdDID0gWF8wMDAxMF8wMDAwMCkKIyAKIyB0ZW1wX2RhdGEgPSAgcmF3X3RlbXBzICU+JQojICAgc2VsZWN0KGRhdGUsIGhvdXIsICJ0ZW1wIiA9IGRlZ0MpCiMgCiMgd3JpdGUuY3N2KHRlbXBfZGF0YSwgZmlsZSA9ICIuL091dHB1dC9EYXRhL2NoYW1wbGFpbl90ZW1wcy5jc3YiLCByb3cubmFtZXMgPSBGKQpgYGAKCkNvbGxlY3Rpb25zIGJlZ2FuIGluIGxhdGUgTWF5IDIwMjMuIFNldmVyYWwgZ2FwcyBhcmUgcHJlc2VudCwgYnV0IGNvbGxlY3Rpb25zIGhhdmUgY29udGludWVkIGF0IHJvdWdobHkgd2Vla2x5IGludGVydmFscyBzaW5jZSB0aGVuLiBDb3BlcG9kcyBmcm9tIGByIGxlbmd0aCh1bmlxdWUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpYCBjb2xsZWN0aW9ucyB3ZXJlIHVzZWQgdG8gbWFrZSBhIHRvdGFsIG9mIGByIGRpbShmdWxsX2RhdGEpWzFdYCB0aGVybWFsIGxpbWl0IG1lYXN1cmVtZW50cy4gT3ZlciB0aGlzIHRpbWUgcGVyaW9kLCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlcyByYW5nZWQgZnJvbSBgciBwYXN0ZShtaW4oZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCksICIgdG8gIiwgbWF4KGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApLCBzZXAgPSAiIilgwrBDLiAgICAgCgpUaGVyZSBpcyBzdWJzdGFudGlhbCB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMgYWNyb3NzIHRoZSBzcGVjaWVzIGNvbGxlY3RlZC4gVGhlcmUgaXMgYWxzbyBzb21lIGRlZ3JlZSBvZiB2YXJpYXRpb24gd2l0aGluIHRoZSBzcGVjaWVzLCB3aXRoIHRoZXJtYWwgbGltaXRzIGluY3JlYXNpbmcgc2xpZ2h0bHkgZHVyaW5nIHRoZSBzdW1tZXIuICAgIAoKYGBge3IgbWFpbi1maWctY3RtYXgtdGltZXNlcmllcywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9CiMjIERhaWx5IHZhbHVlcyBmb3IgdGhlIHBlcmlvZCBleGFtaW5lZCBieSBkYXRhc2V0CmNvbGxlY3Rpb25fY29uZGl0aW9ucyA9IHRlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wLAogICAgICAgICBkYXRlID0gYXMuRGF0ZShkYXRlKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgIAogIGZpbHRlcihkYXRlID49IChtaW4oYXMuRGF0ZShmdWxsX2RhdGEkY29sbGVjdGlvbl9kYXRlKSkgLSA3KSkgJT4lIAogIGxlZnRfam9pbih1bmlxdWUoc2VsZWN0KGZ1bGxfZGF0YSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApKSwgYnkgPSBqb2luX2J5KGRhdGUgPT0gY29sbGVjdGlvbl9kYXRlKSkKCiMjIE1lYW4gZmVtYWxlIHRoZXJtYWwgbGltaXRzIGZvciBlYWNoIHNwZWNpZXMsIGdyb3VwZWQgYnkgY29sbGVjdGlvbgpzcGVjaWVzX3N1bW1hcmllcyA9IGZ1bGxfZGF0YSAlPiUgIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpLAogICAgICAgICAgICAiY3RtYXhfc3RfZXJyIiA9IChzZChjdG1heCkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJjdG1heF92YXIiID0gdmFyKGN0bWF4KSwgCiAgICAgICAgICAgICJtZWFuX3NpemUiID0gbWVhbihzaXplKSwKICAgICAgICAgICAgInNpemVfc3RfZXJyIiA9IChzZChzaXplKSAvIHNxcnQoc2FtcGxlX3NpemUpKSwKICAgICAgICAgICAgInNpemVfdmFyIiA9IHZhcihzaXplKSkgJT4lICAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGFycmFuZ2UoZGVzYyhzYW1wbGVfc2l6ZSkpCgphZHVsdF9zdW1tYXJpZXMgPSBmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpLAogICAgICAgICAgICAiY3RtYXhfc3RfZXJyIiA9IChzZChjdG1heCkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJjdG1heF92YXIiID0gdmFyKGN0bWF4KSwgCiAgICAgICAgICAgICJtZWFuX3NpemUiID0gbWVhbihzaXplKSwKICAgICAgICAgICAgInNpemVfc3RfZXJyIiA9IChzZChzaXplKSAvIHNxcnQoc2FtcGxlX3NpemUpKSwKICAgICAgICAgICAgInNpemVfdmFyIiA9IHZhcihzaXplKSkgJT4lICAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGFycmFuZ2UoZGVzYyhzYW1wbGVfc2l6ZSkpCgoKdHNlcmllc19kYXRhID0gZnVsbF9kYXRhICU+JSAKICBtdXRhdGUoc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGN0bWF4LCAuZGVzYyA9IFQpKQoKZ2dwbG90KCkgKyAKICBnZW9tX3ZsaW5lKGRhdGEgPSB1bmlxdWUoc2VsZWN0KHRzZXJpZXNfZGF0YSwgY29sbGVjdGlvbl9kYXRlKSksIAogICAgICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSkpLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXk5MCIsCiAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fbGluZShkYXRhID0gY29sbGVjdGlvbl9jb25kaXRpb25zLCAKICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGRhdGUpLCB5ID0gbWVhbl90ZW1wKSwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgIyBnZW9tX2Vycm9yYmFyKGRhdGEgPSBzcGVjaWVzX3N1bW1hcmllcywKICAjICAgICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgIyAgICAgICAgICAgICAgICAgICB5bWluID0gbWVhbl9jdG1heCAtIGN0bWF4X3N0X2VyciwgeW1heCA9IG1lYW5fY3RtYXggKyBjdG1heF9zdF9lcnIsCiAgIyAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBzcF9uYW1lKSwKICAjICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLAogICMgICAgICAgICAgICAgICB3aWR0aCA9IDUsIGxpbmV3aWR0aCA9IDEpICsKICAjIGdlb21fcG9pbnQoZGF0YSA9IGFkdWx0X3N1bW1hcmllcywgCiAgIyAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9jdG1heCwgY29sb3VyID0gc3BfbmFtZSwgc2l6ZSA9IHNhbXBsZV9zaXplKSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSB0c2VyaWVzX2RhdGEsIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSksCiAgICAgICAgICAgICBzaXplID0gMiwgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAxLCBoZWlnaHQgPSAwKSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRGF0ZSIsIAogICAgICAgeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiLAogICAgICAgc2l6ZSA9ICJTYW1wbGUgU2l6ZSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmxha2VfdGVtcHMgPSBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShkYXRhID0gY29sbGVjdGlvbl9jb25kaXRpb25zLCAKICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGRhdGUpLCB5ID0gbWVhbl90ZW1wKSwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKVGVtcGVyYXR1cmVzIG9ic2VydmVkIGF0IHRoZSB0aW1lIG9mIGNvbGxlY3Rpb24gY2xvc2VseSByZXNlbWJsZWQgdGhlIG1heGltdW0gZGFpbHkgdGVtcGVyYXR1cmUgZnJvbSB0aGUgdGVtcGVyYXR1cmUgc2Vuc29yIGRhdGEuIE1heGltdW0gdGVtcGVyYXR1cmUgd2FzIHVzZWQgYXMgYSBwcm94eSBpbnN0ZWFkIG9mIG1lYW4gdGVtcGVyYXR1cmUgYXMgY29sbGVjdGlvbnMgd2VyZSB1c3VhbGx5IG1hZGUgZHVyaW5nIGFmdGVybm9vbnMgb3IgZWFybHkgZXZlbmluZ3MsIGp1c3QgZm9sbG93aW5nIHRoZSB3YXJtZXN0IHBhcnQgb2YgdGhlIGRheS4gCgpgYGB7ciBzdXBwLWZpZy10ZW1wLWFjYywgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodD02fQpjb2xsZWN0aW9uX2NvbmRpdGlvbnMgJT4lIAogIGRyb3BfbmEoY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IG1heF90ZW1wLCB5ID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiBmcm9tIFNlbnNvciAowrBDKSIsCiAgICAgICB5ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArIAogIHRoZW1lX21hdHQoKQpgYGAKCmBgYHtyIG1pc2Mtcm91bmQtc3VtbWFyeS0yLCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTEsIGluY2x1ZGUgPSBGfQpnZ3Bsb3QoKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IAogICAgICAgICAgICAgICBjKG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICAgICAgICBtaW4oZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCkpLCAKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gYygyLDEpLCAKICAgICAgICAgICAgIGFscGhhID0gMC41KSArIAogIGdlb21fYmFyKGRhdGEgPSB1bmlxdWUoc2VsZWN0KGZ1bGxfZGF0YSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApKSwgCiAgICAgICAgICAgYWVzKHggPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICAgIHN0YXQgPSAiaWRlbnRpdHkiLAogICAgICAgICAgIGZpbGwgPSAiZ3JleTMwIikgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBmdWxsX2RhdGEsIAogICAgICAgICAgICAgYWVzKHggPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjdG1heCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuNywgaGVpZ2h0ID0gMCksCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTMwIiwKICAgICAgICAgICAgIGFscGhhID0gMC41KSArIAogIHlsaW0oLTMsIDQwKSArIAogIGNvb3JkX3BvbGFyKHN0YXJ0ID0gMCkgKyAKICB0aGVtZV92b2lkKCkKYGBgCgoKU2l6ZSBhbHNvIHZhcmllZCwgYnV0IHByaW1hcmlseSBiZXR3ZWVuIHJhdGhlciB0aGFuIHdpdGhpbiBzcGVjaWVzLiAKCmBgYHtyIHN1cHAtZmlnLXNpemUtdGltZXNlcmllcywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9CmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCAKICAjICAgICAgICAgICAgICAgICAgIHltaW4gPSBtZWFuX2N0bWF4IC0gY3RtYXhfc3RfZXJyLCB5bWF4ID0gbWVhbl9jdG1heCArIGN0bWF4X3N0X2VyciwKICAjICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IHNwX25hbWUpLAogICMgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksCiAgIyAgICAgICAgICAgICAgIHdpZHRoID0gNSwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBtZWFuX3NpemUgKiA0MCwgY29sb3VyID0gc3BfbmFtZSwgc2l6ZSA9IHNhbXBsZV9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBuYW1lID0gIlRlbXBlcmF0dXJlIiwgIyBGZWF0dXJlcyBvZiB0aGUgZmlyc3QgYXhpcwogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+Li80MCwgbmFtZT0iUHJvc29tZSBMZW5ndGggKG1tKSIpLCAjIEFkZCBhIHNlY29uZCBheGlzIGFuZCBzcGVjaWZ5IGl0cyBmZWF0dXJlcwogICAgYnJlYWtzID0gYygwLDUsMTAsMTUsMjAsMjUsMzApCiAgKSArIAogIGxhYnMoeCA9ICJEYXRlIiwgCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciBtaXNjLXRyYWl0LWRveS1mZWF0dXJlLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDcsIGluY2x1ZGUgPSBGfQojU2hvd24gYmVsb3cgaXMgQ1RtYXggYW5kIGJvZHkgc2l6ZSBmb3IgdGhlIHNwZWNpZXMgd2l0aCB0aGUgbW9zdCBkYXRhICgqU2tpc3RvZGlhcHRvbXVzKiwgKkwuIG1pbnV0dXMqLCAqTC4gc2ljaWxpcyosIGFuZCAqRXBpc2NodXJhKiksIHBsb3R0ZWQgYWdhaW5zdCB0aGUgZGF5IG9mIHRoZSB5ZWFyIGZvciBlYWNoIHNleC9zdGFnZSBzZXBhcmF0ZWx5LiAKCmN0bWF4X2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF9ncmlkKHNwX25hbWV+c2V4KSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgdGhlIFllYXIiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpzaXplX2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemUsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgWWVhciIsIAogICAgICAgeSA9ICJTaXplIChtbSkiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ2FycmFuZ2UoY3RtYXhfZmVhdHVyZSwgc2l6ZV9mZWF0dXJlLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gIm5vbmUiKQpgYGAKCmBgYHtyIHNwLW9jY3VyZW5jZXMsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9CnNhbXBsZV9kYXRlc19wbG90ID0gZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNwX25hbWUgIT0gIk9zcGhyYW50aWN1bSBsYWJyb25lY3R1bSIpICU+JSAKICBtdXRhdGUoc3BfbmFtZSA9IGFzLmZhY3RvcihzcF9uYW1lKSwKICAgICAgICAgc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGN0bWF4KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCAKICAgICAgICAgICAgIHkgPSBzcF9uYW1lLCBmaWxsID0gc3BfbmFtZSkpICsgCiAgIyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhc19kYXRlKAogICMgICBjKCIyMDIzLTA1LTAxIiwKICAjICAgICAiMjAyMy0wOS0wMSIsCiAgIyAgICAgIjIwMjQtMDEtMDEiLAogICMgICAgICIyMDI0LTA1LTAxIikpLAogICMgICBjb2xvdXIgPSAiZ3JleSIsCiAgIyAgIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhiYW5kd2lkdGggPSAzMCwKICAgICAgICAgICAgICAgICAgICAgIGppdHRlcmVkX3BvaW50cyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2hhcGUgPSAyMSwKICAgICAgICAgICAgICAgICAgICAgIHBvaW50X3NpemUgPSAxLAogICAgICAgICAgICAgICAgICAgICAgcG9pbnRfY29sb3VyID0gImdyZXkzMCIsCiAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuNiwKICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC45LAogICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9wb2ludHNfaml0dGVyKAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSAwLjEsIHdpZHRoID0gMCkpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIzIG1vbnRocyIsCiAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiViIikgKyAKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjKCIyMDIzLTA0LTI1IiwgIjIwMjQtMDYtMDEiKSkpICsgCiAgbGFicyh4ID0gIkRheSBvZiBZZWFyIiwgCiAgICAgICB5ID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogICN0aGVtZV9yaWRnZXMoZ3JpZCA9IFQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgpUaGUgc2FtcGxlcyBjYXB0dXJlZCB0aGUgYnJvYWQgc2Vhc29uYWwgY2hhbmdlcyBpbiBjYWxhbm9pZCBjb3BlcG9kIGNvbW11bml0eSBjb21wb3NpdGlvbiBpbiB0aGUgbGFrZS4gV2Ugbm90ZSwgaG93ZXZlciwgdGhhdCByYXJlIHNwZWNpZXMgKGUuZy4gKlNlbmVjZWxsYSogYW5kICpMaW1ub2NhbGFudXMqKSB3ZXJlIG9mdGVuIHByZWZlcmVudGlhbGx5IHNhbXBsZWQsIHNvIGFyZSBvdmVyLXJlcHJlc2VudGVkIGluIHRoZSBkYXRhIHNldC4gCgpgYGB7ciBzdXBwLWZpZy1zcC1wcm9wcywgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA1fQphZHVsdF9zdW1tYXJpZXMgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKGNvbGxlY3Rpb25fbnVtID0gYXMubnVtZXJpYyhmYWN0b3IoY29sbGVjdGlvbl9kYXRlKSkpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUpICU+JSAgCiAgYXJyYW5nZShjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBzZWxlY3Qoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX251bSwgc2FtcGxlX3NpemUpICU+JSAKICBtdXRhdGUoc2FtcGxlX3NpemUgPSByZXBsYWNlX25hKHNhbXBsZV9zaXplLCAwKSkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShzYW1wbGVfc2l6ZSksCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBzYW1wbGVfc2l6ZSAvIHRvdGFsLAogICAgICAgICBjb2xsZWN0aW9uX2RhdGUgPSBsdWJyaWRhdGU6OmFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnRhZ2UsIGZpbGwgPSBzcF9uYW1lKSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLDEpKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIERhdGUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIsIAogICAgICAgZmlsbCA9ICJTcGVjaWVzIikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKClRocm91Z2hvdXQgdGhlIHNlYXNvbiwgdGhlIHByZXZhbGVuY2Ugb2YgdmFyaW91cyB1bmlkZW50aWZpZWQgcGF0aG9nZW5zIGFsc28gdmFyaWVkLCB3aXRoIHZlcnkgbGl0dGxlIGluZmVjdGlvbiBvYnNlcnZlZCBkdXJpbmcgdGhlIFdpbnRlciBhbmQgU3ByaW5nLiAKCmBgYHtyIHN1cHAtZmlnLXBhdGhvZ2VuLXByb3BzLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpwYXRob2dlbl9jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJjbG91ZHkiID0gImhvbmV5ZGV3MyIsICJzcG90IiA9ICJhbnRpcXVld2hpdGUzIiwgIm90aGVyIiA9ICJ0b21hdG8zIikKCmZ1bGxfZGF0YSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGV2X2VnZ3MsIHBhdGhvZ2VuLCBsaXBpZHMsIHNwX25hbWUsIHNleCkgJT4lIAogIGdyb3VwX2J5KCkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KHBhdGhvZ2VuKSAlPiUgCiAgZmlsdGVyKHBhdGhvZ2VuICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9ICJjb2xsZWN0aW9uX2RhdGUiLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gcGF0aG9nZW4sIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbiwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0obm8sIGNsb3VkeSwgc3BvdCwgb3RoZXIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCBjbG91ZHksIHNwb3QsIG90aGVyKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGF0aG9nZW4iLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBwYXRob2dlbiA9IGZjdF9yZWxldmVsKHBhdGhvZ2VuLCAibm8iLCAiY2xvdWR5IiwgInNwb3QiLCAib3RoZXIiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBwYXRob2dlbikpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYXRob2dlbl9jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIlBhdGhvZ2VuIikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKClRoZSB0cmFuc3BhcmVudCBib2RpZXMgb2YgdGhlc2UgY29wZXBvZHMgYWxzbyBhbGxvd2VkIHVzIHRvIGV4YW1pbmUgc2Vhc29uYWwgcGF0dGVybnMgaW4gbGlwaWQgcmVzZXJ2ZXMgYW5kIGluIHRoZSBwcm9kdWN0aW9uIG9mIGVnZ3MuIE1hdHVyaW5nIG9vY3l0ZXMgYXJlIHZpc2libGUgaW4gZmVtYWxlIGNvcGVwb2RzIGJlZm9yZSB0aGV5IGFyZSByZWxlYXNlZC4gVGhlcmUgd2FzIG5vIHN0cm9uZyBzZWFzb25hbCBjeWNsZSBpbiB0aGUgcHJvZHVjdGlvbiBvZiB0aGVzZSBlZ2dzIGluIGFueSBzcGVjaWVzLCBhbmQgaW5zdGVhZCwgZmVtYWxlcyB3ZXJlIHJlcHJvZHVjdGl2ZWx5IGFjdGl2ZSB0aHJvdWdob3V0IHRoZWlyIHJlc3BlY3RpdmUgc2Vhc29ucyBvZiBvY2N1cmVuY2UuIAoKYGBge3Igc3VwcC1maWctZGV2ZWdncy1wcm9wcywgZmlnLmhlaWdodCA9IDEyLCBmaWcud2lkdGggPSA4fQpkZXZfZWdnc19jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJ5ZXMiID0gImxpZ2h0Ymx1ZTMiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KGRldl9lZ2dzKSAlPiUgCiAgZmlsdGVyKGRldl9lZ2dzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoImNvbGxlY3Rpb25fZGF0ZSIsICJzcF9uYW1lIiksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBkZXZfZWdncywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgeWVzKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhubywgeWVzKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGV2X2VnZ3MiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBkZXZfZWdncyA9IGZjdF9yZWxldmVsKGRldl9lZ2dzLCAibm8iLCAieWVzIikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGNvbGxlY3Rpb25fZGF0ZSwgbmVzdGluZyhzcF9uYW1lLCBkZXZfZWdncyksIGZpbGwgPSBsaXN0KHBlcmNlbnQgPSAxKSkgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gaWZfZWxzZShpcy5uYSh0b3RhbCkgJiBkZXZfZWdncyA9PSAieWVzIiwgMCwgcGVyY2VudCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50LCBmaWxsID0gZGV2X2VnZ3MpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGRldl9lZ2dzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiRGV2ZWxvcGluZyBcbkVnZ3MiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKVGhlIHByZXNlbmNlIG9mIGxpcGlkcyB2YXJpZWQgYWNyb3NzIHNwZWNpZXMsIHdpdGggb25seSAqTC4gbWludXR1cyosICpMLiBzaWNpbGlzKiwgYW5kICpMaW1ub2NhbGFudXMqIHJlZ3VsYXJseSBwb3NzZXNzaW5nIGxpcGlkIHN0b3Jlcy4gCgpgYGB7ciBzdXBwLWZpZy1saXBpZHMtcHJvcHMsIGZpZy5oZWlnaHQgPSAxMiwgZmlnLndpZHRoID0gOH0KbGlwaWRfY29scyA9IGMoIm5vIiA9ICJncmV5OTUiLCAieWVzIiA9ICJzaWVubmEyIikKCmZ1bGxfZGF0YSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGV2X2VnZ3MsIHBhdGhvZ2VuLCBsaXBpZHMsIHNwX25hbWUsIHNleCkgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBjb3VudChsaXBpZHMpICU+JSAKICBmaWx0ZXIobGlwaWRzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoImNvbGxlY3Rpb25fZGF0ZSIsICJzcF9uYW1lIiksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBsaXBpZHMsIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbiwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0obm8sIHllcykpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobm8sIHllcyksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImxpcGlkcyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIGxpcGlkcyA9IGZjdF9yZWxldmVsKGxpcGlkcywgIm5vIiwgInllcyIpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShjb2xsZWN0aW9uX2RhdGUsIG5lc3Rpbmcoc3BfbmFtZSwgbGlwaWRzKSwgZmlsbCA9IGxpc3QocGVyY2VudCA9IDEpKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBpZl9lbHNlKGlzLm5hKHRvdGFsKSAmIGxpcGlkcyA9PSAieWVzIiwgMCwgcGVyY2VudCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50LCBmaWxsID0gbGlwaWRzKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LiwgbmNvbCA9IDEpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBsaXBpZF9jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIkxpcGlkc1xuUHJlc2VudCIpICsgCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoKSkKYGBgCgoKIyMgVGVtcGVyYXR1cmUgVmFyaWFiaWxpdHkKTGFrZSBDaGFtcGxhaW4gaXMgaGlnaGx5IHNlYXNvbmFsLCB3aXRoIGJvdGggYXZlcmFnZSB0ZW1wZXJhdHVyZXMgYW5kIHRlbXBlcmF0dXJlIHZhcmlhYmlsaXR5IGNoYW5naW5nIHRocm91Z2hvdXQgdGhlIHllYXIuIFRoZXNlIHBhdHRlcm5zIGluIHRoZSBleHBlcmllbmNlZCB0aGVybWFsIGVudmlyb25tZW50IG1heSBkcml2ZSB0aGUgb2JzZXJ2ZWQgdmFyaWF0aW9uIGluIGNvcGVwb2QgdGhlcm1hbCBsaW1pdHMuIEhvd2V2ZXIsIHRoZSB0aW1lIHBlcmlvZCBhZmZlY3RpbmcgY29wZXBvZCB0aGVybWFsIGxpbWl0cyBpcyB1bmtub3duLiBEZXBlbmRpbmcgdGhlIG9uIHRoZSBkdXJhdGlvbiBvZiB0aW1lIGNvbnNpZGVyZWQsIHRoZXJlIGFyZSBsYXJnZSBjaGFuZ2VzIGluIHRoZSBleHBlcmllbmNlZCBlbnZpcm9ubWVudCwgaW4gcGFydGljdWxhciByZWdhcmRpbmcgdGhlIHRlbXBlcmF0dXJlIHJhbmdlIGFuZCB2YXJpYW5jZS4gQ29uc2lkZXIgZm9yIGV4YW1wbGUgdGhyZWUgdGltZSBwZXJpb2RzOiB0aGUgZGF5IG9mIGNvbGxlY3Rpb24sIG9uZSB3ZWVrIHByaW9yIHRvIGNvbGxlY3Rpb24sIGFuZCBmb3VyIHdlZWtzIHByaW9yIHRvIGNvbGxlY3Rpb24uIFdoaWxlIHRoZSBvdmVyYWxsIHBhdHRlcm4gaXMgc2ltaWxhciwgd2UgY2FuIHNlZSB0aGF0LCB1bnN1cnByaXNpbmdseSwgY29uc2lkZXJpbmcgbG9uZ2VyIHBlcmlvZHMgb2YgdGltZSByZXN1bHRzIGluIGxhcmdlciByYW5nZXMgYW5kIHNsaWdodGx5IGNoYW5nZXMgdGhlIHBhdHRlcm4gb2YgdmFyaWFuY2UgZXhwZXJpZW5jZWQuIAoKYGBge3IgZGFpbHktdGVtcC1kYXRhLCBpbmNsdWRlID0gRn0KIyMgRGFpbHkgdmFsdWVzCmRhaWx5X3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wKQoKZGF5X3ByaW9yX3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoZGF0ZSA9IGRhdGUgKyAxKSAlPiUgCiAgcmVuYW1lX3dpdGgoLmZuID0gfiBwYXN0ZTAoInByaW9yX2RheV8iLCAueCksIC5jb2xzID0gYygtZGF0ZSkpCgpkYWlseV9wbG90ID0gZGFpbHlfdGVtcF9kYXRhICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiAgZ2d0aXRsZSgiRGFpbHkgVmFsdWVzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIHByZWRpY3RvcnMtZnVuY3Rpb259CiMjIERlZmluaW5nIHRoZSBmdW5jdGlvbiB0byBnZXQgcHJlZGljdG9yIHZhbHVlcyBmb3IgcGVyaW9kcyBvZiBkaWZmZXJlbnQgbGVuZ3RocwpnZXRfcHJlZGljdG9ycyA9IGZ1bmN0aW9uKGRhaWx5X3ZhbHVlcywgcmF3X3RlbXAsIG5fZGF5cyl7CiAgcHJlZml4ID0gc3RyX3JlcGxhY2VfYWxsKHhmdW46Om51bWJlcnNfdG9fd29yZHMobl9kYXlzKSwgcGF0dGVybiA9ICIgIiwgcmVwbGFjZW1lbnQgPSAiLSIpCiAgCiAgbWVhbl92YWx1ZXMgPSBkYWlseV92YWx1ZXMgJT4lIAogICAgdW5ncm91cCgpICU+JSAKICAgIG11dGF0ZShtZWFuX21heCA9IHNsaWRlX3ZlYygueCA9IG1heF90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpLAogICAgICAgICAgIG1lYW5fbWluID0gc2xpZGVfdmVjKC54ID0gbWluX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCksCiAgICAgICAgICAgbWVhbl9yYW5nZSA9IHNsaWRlX3ZlYygueCA9IHJhbmdlX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCkpICU+JSAKICAgIHNlbGVjdChkYXRlLCBtZWFuX21heCwgbWVhbl9taW4sIG1lYW5fcmFuZ2UpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKQogIAogIHBlcmlvZF92YWx1ZXMgPSByYXdfdGVtcCAlPiUgCiAgICBtdXRhdGUobWVhbiA9IHNsaWRlX2luZGV4X21lYW4odGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtYXggPSBzbGlkZV9pbmRleF9tYXgodGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWluID0gc2xpZGVfaW5kZXhfbWluKHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWVkID0gc2xpZGVfaW5kZXhfZGJsKHRlbXAsIC5pID0gZGF0ZSwgLmJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCwgLmYgPSBtZWRpYW4pLAogICAgICAgICAgIHZhciA9IHNsaWRlX2luZGV4X2RibCh0ZW1wLCAuaSA9IGRhdGUsIC5iZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZiA9IHZhciksCiAgICAgICAgICAgcmFuZ2UgPSBtYXggLSBtaW4pICU+JSAgCiAgICBzZWxlY3QoLXRlbXApICU+JSAgCiAgICBkaXN0aW5jdCgpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKSU+JSAKICAgIGlubmVyX2pvaW4obWVhbl92YWx1ZXMsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgIAogICAgZHJvcF9uYSgpCiAgCiAgcmV0dXJuKHBlcmlvZF92YWx1ZXMpCn0KYGBgCgpgYGB7ciBwcmVkaWN0b3JzLWFuZC1wbG90cywgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTUsIGluY2x1ZGUgPSBGfQojICMjIEdldHRpbmcgcHJlZGljdG9yIHZhcmlhYmxlcyBmb3IgZGlmZmVyZW50IHBlcmlvZHMKIyAKIyAjIyMgU2hvcnQgKHRocmVlIGRheXMpCiMgdGhyZWVfZGF5X3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMykKIyAKIyAjIyMgT05FIFdFRUsKd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gNykKCndlZWtfcGxvdCA9IHdlZWtfdGVtcHMgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygic2V2ZW5fZGF5X21lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X21heCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9taW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X3JhbmdlIikpICU+JQogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsKICBnZ3RpdGxlKCJPbmUgV2VlayIpICsKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgVFdPIFdFRUtTCiMgdHdvX3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMTQpCiMgCiMgdHdvX3dlZWtfcGxvdCA9IHR3b193ZWVrX3RlbXBzICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiMgICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygiZm91cnRlZW5fZGF5X21lYW4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9tZWQiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9tYXgiLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfbWluIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X3ZhciIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X3JhbmdlIikpICU+JSAKIyAgIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAojICAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKIyAgICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAojICAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKIyAgICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKIyAgICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAojICAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgojICAgKSkgKyAKIyAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArIAojICAgZ2d0aXRsZSgiVHdvIFdlZWtzIikgKyAKIyAgIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiMgICAgICAgIHggPSAiIikgKyAKIyAgIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAojICAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgRk9VUiBXRUVLUwpmb3VyX3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAyOCkKCmZvdXJfd2Vla19wbG90ID0gZm91cl93ZWVrX3RlbXBzICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lCiAgZmlsdGVyKHBhcmFtZXRlciAlaW4lIGMoInR3ZW50eS1laWdodF9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9tYXgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21pbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9yYW5nZSIpKSAlPiUKICBtdXRhdGUocGFyYW1ldGVyID0gcGFzdGUod29yZChwYXJhbWV0ZXIsIHN0YXJ0ID0gMywgc2VwID0gZml4ZWQoIl8iKSksICJfdGVtcCIsIHNlcCA9ICIiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygKICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAogICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAogICAgIm1heF90ZW1wIiA9ICJ0b21hdG8iLAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArCiAgZ2d0aXRsZSgiRm91ciBXZWVrcyIpICsKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgRUlHSFQgV0VFS1MKIyBlaWdodF93ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA1NikKIyAKIyBlaWdodF93ZWVrX3Bsb3QgPSBlaWdodF93ZWVrX3RlbXBzICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiMgICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygiZmlmdHktc2l4X2RheV9tZWFuIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21lZCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV9tYXgiLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21pbiIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfdmFyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X3JhbmdlIikpICU+JSAKIyAgIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAojICAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKIyAgICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAojICAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKIyAgICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKIyAgICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAojICAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgojICAgKSkgKyAKIyAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArIAojICAgZ2d0aXRsZSgiRWlnaHQgV2Vla3MiKSArIAojICAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKIyAgICAgICAgeCA9ICIiKSArIAojICAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiMgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIApnZ2FycmFuZ2UoZGFpbHlfcGxvdCwgd2Vla19wbG90LCBmb3VyX3dlZWtfcGxvdCwgCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbnJvdyA9IDEsIGxlZ2VuZCA9ICJib3R0b20iKQpgYGAKCmBgYHtyLCBpbmNsdWRlID0gRn0KI1RoZSBkaWZmZXJlbnQgdGltZSBwZXJpb2RzIGV4YW1pbmVkIGJ5IHRoaXMgY2xpbWF0ZSBkYXRhIGhpZ2hsaWdodHMgdGhhdCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWluaW11bSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgY2hhbmdlcyBiYXNlZCBvbiB0aGUgd2luZG93IGV4YW1pbmVkLiBGb3IgZXhhbXBsZSwgbWluaW11bSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgZXhwZXJpZW5jZWQgb3ZlciB3ZWVrbHkgaW50ZXJ2YWxzIGFyZSBjbG9zZWx5IGxpbmtlZCwgd2hlcmVhcyB0aGVyZSBpcyBhIGRpc3RpbmN0IHNlYXNvbmFsIGN5Y2xlIGluIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIHBlcmlvZHMgb2YgZm91ciB3ZWVrcy4gCgpvbmVfd2Vla19kb3lfZGF0YSA9IHdlZWtfdGVtcHMgJT4lIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpKQoKb25lX3dlZWtfdGVtcF9jaXJjbGUgPSBnZ3Bsb3Qob25lX3dlZWtfZG95X2RhdGEsIGFlcyh4ID0gc2V2ZW5fZGF5X21lYW5fbWF4LCB5ID0gc2V2ZW5fZGF5X21lYW5fbWluLCBjb2xvdXIgPSBkb3kpKSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIoCiAgICBoaWdoID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZCA9ICJjb3JhbDIiLAogICAgbG93ID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZHBvaW50ID0gMTgyLjUpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiAowrBDKSIsCiAgICAgICB5ID0gIk1pbi4gVGVtcC4gKMKwQykiKSArIAogIGdndGl0bGUoIk9uZSBXZWVrIikgKyAKICB0aGVtZV9tYXR0KCkKCmZvdXJfd2Vla19kb3lfZGF0YSA9IGZvdXJfd2Vla190ZW1wcyAlPiUgCiAgbXV0YXRlKGRveSA9IHlkYXkoZGF0ZSkpCgpmb3VyX3dlZWtfdGVtcF9jaXJjbGUgPSBnZ3Bsb3QoZm91cl93ZWVrX2RveV9kYXRhLCBhZXMoeCA9IGB0d2VudHktZWlnaHRfZGF5X21heGAsIHkgPSBgdHdlbnR5LWVpZ2h0X2RheV9taW5gLCBjb2xvdXIgPSBkb3kpKSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIoCiAgICBoaWdoID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZCA9ICJjb3JhbDIiLAogICAgbG93ID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZHBvaW50ID0gMTgyLjUpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBnZ3RpdGxlKCJGb3VyIFdlZWsiKSArIAogIHRoZW1lX21hdHQoKQoKZ2dhcnJhbmdlKG9uZV93ZWVrX3RlbXBfY2lyY2xlLCBmb3VyX3dlZWtfdGVtcF9jaXJjbGUsCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGfQojVGhlIHRoZXJtYWwgZW52aXJvbm1lbnQgb3ZlciBhbnkgcGVyaW9kIG9mIHRpbWUgbWF5IGRyaXZlIHBhdHRlcm5zIGluIHRoZXJtYWwgYWNjbGltYXRpb24uIFRvIGV4cGxvcmUgdGhlIHBvdGVudGlhbCBlZmZlY3RzIG9mIGRpZmZlcmVudCBhY2NsaW1hdGlvbiB3aW5kb3dzLCB3ZSBleGFtaW5lZCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGVybWFsIGxpbWl0cyBhbmQgZGlmZmVyZW50IHJlcHJlc2VudGF0aW9ucyBvZiB0aGUgdGhlcm1hbCBlbnZpcm9ubWVudCBmb3IgZGlmZmVyZW50IHBlcmlvZHMgb2YgdGltZS4gU2hvd24gYmVsb3cgYXJlIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgZm9yIHRoZXNlIHJlbGF0aW9uc2hpcHMuIEVhY2ggZmFjZXQgc2hvd3MgdGhlIHJlbGF0aW9uc2hpcCBmb3IgYSBkaWZmZXJlbnQgZGltZW5zaW9uIG9mIHRoZSB0aGVybWFsIGVudmlyb25tZW50LiBDb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYXJlIHBsb3R0ZWQgZm9yIGRpZmZlcmVudCBkdXJhdGlvbnMsIGZvciBzcGVjaWVzIHRoYXQgd2VyZSBjb2xsZWN0ZWQgbW9yZSB0aGFuIGZpdmUgdGltZXMuIE9ubHkgZGF0YSBmb3IgbWF0dXJlIGZlbWFsZSBjb3BlcG9kcyB3YXMgaW5jbHVkZWQuIAoKI1dlIGNhbiBzZWUgdGhhdCwgaW4gZ2VuZXJhbCwgY29wZXBvZHMgYXJlIHJlc3BvbmRpbmcgdG8gcHJveGltYXRlIGN1ZXMgZnJvbSB0aGUgdGhlcm1hbCBlbnZpcm9ubWVudCwgd2l0aCBjb3JyZWxhdGlvbnMgZ2VuZXJhbGx5IGRyb3BwaW5nIG9mZiBzdWJzdGFudGlhbGx5IGFzIGFjY2xpbWF0aW9uIHdpbmRvdyBkdXJhdGlvbiBpbmNyZWFzZXMuIEFuIGV4Y2VwdGlvbiBpcyAqRXBpc2NodXJhIGxhY3VzdHJpcyosIHdoaWNoIGFwcGVhcnMgdG8gYmUgcmVzcG9uZGluZyB0byBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIGEgMjAgZGF5IHRpbWUgcGVyaW9kLiAKCiMjIyBQdWxsaW5nIHByZWRpY3RvcnMgYW5kIG1lYXN1cmluZyBjb3JyZWxhdGlvbnMgZm9yIG11Y2ggZmluZXIgdGltZXNjYWxlczsgMS01NiBkYXlzCgpudW1fY29sbHMgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBzcF9uYW1lKSAlPiUgIAogIGRpc3RpbmN0KCkgJT4lICAKICBjb3VudChzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKG4gPj0gNSkKCmNvcnJfdmFscyA9IGRhdGEuZnJhbWUoKQoKZHVyX3ZhbHMgPSBjKDE6MzApCmZvcihpIGluIGR1cl92YWxzKXsKICAKICBkdXJhdGlvbl90ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSBpKSAlPiUgCiAgICBmaWx0ZXIoZGF0ZSAlaW4lIGFzX2RhdGUodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKSkKICAKICBjb3JyX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiAgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgICBpbm5lcl9qb2luKGR1cmF0aW9uX3RlbXBzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lIAogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGNvbGxlY3Rpb25fdGVtcCwgY29udGFpbnMoImRheV8iKSksCiAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIiwgCiAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJlZGljdG9yIikgJT4lICAKICAgIGdyb3VwX2J5KHNwX25hbWUsIHByZWRpY3RvcikgJT4lIAogICAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRlc3RpbWF0ZSwKICAgICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRwLnZhbHVlLAogICAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMV0sCiAgICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMl0sCiAgICAgICAgICAgICAgLmdyb3VwcyA9ICJrZWVwIikgJT4lIAogICAgZmlsdGVyKHByZWRpY3RvciAhPSAiY29sbGVjdGlvbl90ZW1wIikgJT4lIAogICAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKSAlPiUgCiAgICBzZXBhcmF0ZShwcmVkaWN0b3IsICJfZGF5XyIsIGludG8gPSBjKE5BLCAicGFyYW1ldGVyIikpICU+JSAKICAgIG11dGF0ZShkdXJhdGlvbiA9IGkpCiAgCiAgY29ycl92YWxzID0gYmluZF9yb3dzKGNvcnJfdmFscywgY29ycl9kYXRhKQp9Cgpjb2xsX2NvcnIgPSBmdWxsX2RhdGEgJT4lCiAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkZXN0aW1hdGUsCiAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRwLnZhbHVlLAogICAgICAgICAgICBjaV9sb3cgPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRjb25mLmludFsxXSwKICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJGNvbmYuaW50WzJdKSAlPiUgCiAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKSAlPiUgCiAgbXV0YXRlKGR1cmF0aW9uID0gMCwKICAgICAgICAgcGFyYW1ldGVyID0gImNvbGxfdGVtcCIpCgpjb3JyX3ZhbHMgPSBjb3JyX3ZhbHMgJT4lICAKICBtdXRhdGUoZHVyYXRpb24gPSBhcy5udW1lcmljKGR1cmF0aW9uKSkgJT4lIAogIGJpbmRfcm93cyhjb2xsX2NvcnIpCgpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02LCBpbmNsdWRlID0gRn0KY29ycl92YWxzICU+JSAKICBtdXRhdGUocGFyYW1ldGVyID0gZmN0X3JlbGV2ZWwocGFyYW1ldGVyLCBjKCJtaW4iLCAibWF4IiwgInJhbmdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtZWFuIiwgIm1lZCIsICJ2YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lYW5fbWluIiwgIm1lYW5fbWF4IiwgIm1lYW5fcmFuZ2UiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkdXJhdGlvbiwgeSA9IGNvcnJlbGF0aW9uLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKC5+cGFyYW1ldGVyKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMC45KSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkR1cmF0aW9uIChkYXlzKSIsCiAgICAgICB5ID0gIkNvcnJlbGF0aW9uIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQpgYGAKCmBgYHtyIHByZWRpY3Rvci1jb3JyZWxhdGlvbnMsIGluY2x1ZGUgPSBGfQojIFNob3duIGhlcmUgYXJlIHRoZSB0b3AgdGhyZWUgZmFjdG9ycyBmb3IgZWFjaCBzcGVjaWVzLiAKCiMgY29ycl92YWxzID0gZnVsbF9kYXRhICU+JQojICAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAojICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAojICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAojICAgZnVsbF9qb2luKHRlbXBfcHJlZGljdG9ycywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYyhjb2xsZWN0aW9uX3RlbXAsIG1lYW5fdGVtcDp0YWlsKG5hbWVzKC4pLCAxKSksCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIiwgCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJlZGljdG9yIikgJT4lICAKIyAgIGdyb3VwX2J5KHNwX25hbWUsIHByZWRpY3RvcikgJT4lIAojICAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRlc3RpbWF0ZSwKIyAgICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRwLnZhbHVlLAojICAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMV0sCiMgICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMl0pICU+JSAKIyAgIG11dGF0ZShzaWcgPSBpZmVsc2UocC52YWx1ZSA8MC4wNSwgIlNpZy4iLCAiTm9uIFNpZy4iKSkKCmNvcnJfdmFscyAlPiUgIAogIGZpbHRlcihzaWcgPT0gIlNpZy4iKSAlPiUgCiAgZHJvcF9uYShjb3JyZWxhdGlvbikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JQogIGFycmFuZ2UoZGVzYyhjb3JyZWxhdGlvbikpICU+JSAKICBzbGljZV9oZWFkKG4gPSAzKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJQcmVkaWN0b3IiID0gcGFyYW1ldGVyLCAiRHVyYXRpb24iID0gZHVyYXRpb24sICJDb3JyZWxhdGlvbiIgPSBjb3JyZWxhdGlvbiwgIlAtVmFsdWUiID0gcC52YWx1ZSkgJT4lIAogIGtuaXRyOjprYWJsZShhbGlnbiA9ICJjIikKYGBgCgpgYGB7ciBhY2MtZHVyYXRpb24tcGxvdCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NCwgaW5jbHVkZSA9IEZ9CiMgUGhlbm90eXBpYyB2YXJpYXRpb24gKGxpa2UgYWNjbGltYXRpb24gb2YgdGhlcm1hbCBsaW1pdHMpIGlzIGEgcGh5c2lvbG9naWNhbCBwcm9jZXNzLiBkZXBlbmRpbmcgb24gdGhlIG1lY2hhbmlzdGljIHVuZGVycGlubmluZ3MgKGNoYW5nZXMgaW4gSFNQIGV4cHJlc3Npb24sIGV0Yy4pLCB0aGUgYW1vdW50IG9mIHRpbWUgaXQgdGFrZXMgZm9yIGFuIGluZGl2aWR1YWwgdG8gYWNjbGltYXRlIG1heSB2YXJ5IGJhc2VkIG9uIGJvZHkgc2l6ZSAobGFyZ2VyIHNwZWNpZXMsIG1vcmUgY2VsbHMsIG1vcmUgdGltZSByZXF1aXJlZCB0byBhY2NsaW1hdGUpLiBTaG93biBoZXJlIGlzIHRoZSBkdXJhdGlvbiBvZiB0aGUgZW52aXJvbm1lbnRhbCBhY2NsaW1hdGlvbiB3aW5kb3cgdGhlIGNvcGVwb2RzIGFwcGVhciB0byBiZSByZXNwb25kaW5nIHRvLiAgCgptZWFuX3NpemVzID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lICAKICBzdW1tYXJpc2UobWVhbl9zaXplID0gbWVhbihzaXplLCBuYS5ybSA9IFQpKQoKY29ycl92YWxzICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKGNvcnJlbGF0aW9uID09IG1heChjb3JyZWxhdGlvbikpICU+JSAgCiAgaW5uZXJfam9pbihtZWFuX3NpemVzLCBieSA9ICJzcF9uYW1lIikgJT4lIAogIHNlbGVjdChzcF9uYW1lLCBkdXJhdGlvbiwgbWVhbl9zaXplKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IG1lYW5fc2l6ZSwgeSA9IGR1cmF0aW9uKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzcF9uYW1lKSwgCiAgICAgICAgICAgICBzaXplID0gNCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiTWVhbiBGZW1hbGUgU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiQWNjbGltYXRpb24gRHVyYXRpb24iLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKIyMgVHJhaXQgVmFyaWF0aW9uIAoKU2hvd24gYmVsb3cgYXJlIHRoZSBjbHV0Y2ggc2l6ZSBkaXN0cmlidXRpb25zIGZvciB0aGUgdGhyZWUgZGlhcHRvbWlpZCBzcGVjaWVzLCB3aGljaCBwcm9kdWNlIGVnZyBzYWNzIHRoYXQgYWxsb3cgZm9yIGVhc3kgcXVhbnRpZmljYXRpb24gb2YgZmVjdW5kaXR5LiAKCmBgYHtyIHN1cHAtZmlnLWZlY3VuZGl0eS1oaXN0b2dyYW0sIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTEwfQpmdWxsX2RhdGEgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBmZWN1bmRpdHksIGZpbGwgPSBzcF9uYW1lX3N1YikpICsgCiAgZmFjZXRfd3JhcCgufnNwX25hbWVfc3ViLCBuY29sID0gMSkgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJGZWN1bmRpdHkgKCMgRWdncykiKSArCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpPbmUgb2YgdGhlIG1haW4gYWltcyBvZiB0aGlzIHByb2plY3QgaXMgdG8gZXhhbWluZSB0aGUgcGF0dGVybnMgYW5kIHByb2Nlc3NlcyBkcml2aW5nIHZhcmlhdGlvbiBpbiB1cHBlciB0aGVybWFsIGxpbWl0cyBhY3Jvc3MgdGhlc2Ugc3BlY2llcyBvZiBjb3BlcG9kcy4gCgojIyMgVmFyaWF0aW9uIHdpdGggdGVtcGVyYXR1cmUgCgpXZSBleHBlY3Qgb25lIG9mIHRoZSBwcmltYXJ5IGRyaXZlcnMgb2YgY29wZXBvZCB0aGVybWFsIGxpbWl0cyB0byBiZSB0ZW1wZXJhdHVyZS4gVGhlIGNvcnJlbGF0aW9uIGFuYWx5c2lzIGhhcyBzaG93biB0aGF0IHRoZSBjb3BlcG9kcyBhcmUgZ2VuZXJhbGx5IChhbHRob3VnaCBub3QgYWx3YXlzKSByZXNwb25kaW5nIHRvIHRoZSByZWNlbnQgdGhlcm1hbCBlbnZpcm9ubWVudC4gU2hvd24gYmVsb3cgYXJlIHRoZXJtYWwgbGltaXRzLCBib2R5IHNpemUsIGFuZCBmZWN1bmRpdHkgdmFsdWVzIHBsb3R0ZWQgYWdhaW5zdCB0aGUgdGVtcGVyYXR1cmUgYXQgdGhlIHRpbWUgb2YgY29sbGVjdGlvbi4gQWxzbyBzaG93biBpcyB3YXJtaW5nIHRvbGVyYW5jZSwgY2FsY3VsYXRlZCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHVwcGVyIHRoZXJtYWwgbGltaXQgYW5kIHRoZSBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLiAKCldlIGdlbmVyYWxseSBzZWUgYW4gaW5jcmVhc2UgaW4gdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUsIGEgc2xpZ2h0IGRlY3JlYXNlIGluIGJvZHkgc2l6ZSwgYW5kIHZhcmlhYmxlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0ZW1wZXJhdHVyZSBhbmQgZmVjdW5kaXR5LiBBbGwgc3BlY2llcyBtYWludGFpbmVkIHNvbWUgZGVncmVlIG9mIGJ1ZmZlciBiZXR3ZWVuIGVudmlyb25tZW50YWwgdGVtcGVyYXR1cmVzIGFuZCB1cHBlciB0aGVybWFsIGxpbWl0cywgYnV0ICpFcGlzY2h1cmEqIGFuZCAqTC4gbWludXR1cyogYXBwcm9hY2hlZCB0aGVpciB1cHBlciB0aGVybWFsIGxpbWl0cyBkdXJpbmcgdGhlIHdhcm1lc3QgY29sbGVjdGlvbnMgZHVyaW5nIHRoZSBzdW1tZXIuIAoKYGBge3IgbWFpbi1maWctdHJhaXQtY29sbC10ZW1wLXBsb3RzLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9N30KY3RtYXhfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArICAgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfdGVtcCA9IGdncGxvdChmaWx0ZXIoZnVsbF9kYXRhLCBzZXggIT0gImp1dmVuaWxlIiksIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJMZW5ndGggKG1tKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSB3YXJtaW5nX3RvbCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmVnZ3NfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2Uod3RfdGVtcCwgZWdnc190ZW1wLCAKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKCmBgYHtyIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9CnNwX2N0bWF4X3RlbXAgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzcF9uYW1lICE9ICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iKSAlPiUgCiAgbXV0YXRlKHNwX25hbWUgPSBhcy5mYWN0b3Ioc3BfbmFtZSksCiAgICAgICAgIHNwX25hbWUgPSBmY3RfcmVvcmRlcihzcF9uYW1lLCBjdG1heCwgLmRlc2MgPSBUKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpgYGB7ciBtYWluLWZpZy1zcC1zdW1tYXJpZXMsIGZpZy53aWR0aD0xNCwgZmlnLmhlaWdodD01fQpnZ2FycmFuZ2Uoc2FtcGxlX2RhdGVzX3Bsb3QsIHNwX2N0bWF4X3RlbXAsIG5yb3cgPSAxLCAKICAgICAgICAgIGxhYmVscyA9ICJBVVRPIikKYGBgCgoKVGVtcGVyYXR1cmUgZGVwZW5kZW5jZSBpcyByZWxhdGl2ZWx5IHdlYWsgaW4gKkwuIHNpY2lsaXMqLCBlc3BlY2lhbGx5IGF0IGNvb2xlciB0ZW1wZXJhdHVyZXMuIFdlIHdpbGwgcmV0dXJuIHRvIHRoaXMgZmVhdHVyZSBsYXRlciBpbiB0aGUgcmVwb3J0LCBidXQgZm9yIG5vdyB3ZSB3aWxsIG5vdGUgdGhhdCB0aGVyZSBhcmUgdHdvIHNpemUgbW9ycGhzIGluIHRoaXMgc3BlY2llcywgd2hpY2ggYXBwZWFyIHRvIHJlc3BvbmQgZGlmZmVyZW50bHkgdG8gZGVjcmVhc2VzIGluIHRlbXBlcmF0dXJlLiBUaGVyZSBhcmUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgbW9ycGhzIGFuZCBob3cgdGVtcGVyYXR1cmUgYWZmZWN0cyBDVG1heC4gCmBgYHtyIHN1cHAtZmlnLWxzaWMtbW9ycGhzfQptb3JwaF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiICYgc3BlY2llcyA9PSAibGVwdG9kaWFwdG9tdXNfc2ljaWxpcyIpICU+JSAgbXV0YXRlKHNwX25hbWUgPSBjYXNlX3doZW4oCiAgICBzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiAmIHNpemUgPj0gMC44OSB+ICJMYXJnZSIsCiAgICBzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiAmIHNpemUgPCAwLjg5IH4gIlNtYWxsIiwKICAgIC5kZWZhdWx0ID0gc3BfbmFtZQogICkpCgoKZ2dwbG90KG1vcnBoX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKbW9ycGgubW9kZWwgPSBsbShkYXRhID0gbW9ycGhfZGF0YSwgCiAgICAgICAgICAgICAgICAgY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKiBzcF9uYW1lKQoKa25pdHI6OmthYmxlKGNhcjo6QW5vdmEobW9ycGgubW9kZWwsIHR5cGUgPSAiSUlJIiwgdGVzdCA9ICJGIikpCgojc3VtbWFyeShtb3JwaC5tb2RlbCkKCm1vcnBoLmVtID0gZW1tZWFuczo6ZW10cmVuZHMobW9ycGgubW9kZWwsICJzcF9uYW1lIiwgdmFyID0gImNvbGxlY3Rpb25fdGVtcCIpCgprbml0cjo6a2FibGUocGFpcnMobW9ycGguZW0pKQpgYGAKCmBgYHtyIGN0bWF4LXJhbmdlLXBsb3QsIGluY2x1ZGUgPSBGfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJjdG1heF9yYW5nZSIgPSBtYXgoY3RtYXgpIC0gbWluKGN0bWF4KSwKICAgICAgICAgICAgImN0bWF4X3ZhciIgPSB2YXIoY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgIT0gIkxlcHRvZG9yYSBraW5kdGkiKSAlPiUgCiAgZmlsdGVyKHNhbXBsZV9zaXplID4gMykgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3VyID0gImJsYWNrIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCmBgYAoKYGBge3IgY3RtYXgtY29sbC10ZW1wLW1vZGVsLCBpbmNsdWRlID0gRn0KIyBhZHVsdF9kYXRhID0gZnVsbF9kYXRhICU+JSAKIyAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpCgptb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JSAgCiAgZHJvcF9uYShzaXplLCBjdG1heCkgJT4lICAKICBtdXRhdGUodGVtcF9jZW50ID0gc2NhbGUoY29sbGVjdGlvbl90ZW1wLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpLAogICAgICAgICBzaXplX2NlbnQgPSBzY2FsZShzaXplLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpKQoKY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCBjdG1heCB+IHRlbXBfY2VudCAqIHNwX25hbWUpCnNpemVfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCBzaXplIH4gdGVtcF9jZW50ICogc3BfbmFtZSkKZmVjdW5kX3RlbXAubW9kZWwgPSBsbShkYXRhID0gZHJvcF9uYShtb2RlbF9kYXRhLCBmZWN1bmRpdHkpLCBmZWN1bmRpdHkgfiB0ZW1wX2NlbnQgKiBzcF9uYW1lKQoKZmVjdW5kaXR5X3Jlc2lkcyA9IGNiaW5kKGRyb3BfbmEobW9kZWxfZGF0YSwgZmVjdW5kaXR5KSwgImZlY3VuZGl0eV9yZXNpZHMiID0gZmVjdW5kX3RlbXAubW9kZWwkcmVzaWR1YWxzKSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZXhwX2RhdGUsIHJlcGxpY2F0ZSwgc3BlY2llcywgdHViZSwgZmVjdW5kaXR5X3Jlc2lkcykKCmN0bWF4X3Jlc2lkcyA9IGNiaW5kKG1vZGVsX2RhdGEsICJyZXNpZHMiID0gY3RtYXhfdGVtcC5tb2RlbCRyZXNpZHVhbHMsICJzaXplX3Jlc2lkcyIgPSBzaXplX3RlbXAubW9kZWwkcmVzaWR1YWxzKSAlPiUgCiAgbGVmdF9qb2luKGZlY3VuZGl0eV9yZXNpZHMpCgpgYGAKCkNvcGVwb2RzIHNwZW50IHNldmVyYWwgZGF5cyBpbiBsYWIgZHVyaW5nIGV4cGVyaW1lbnRzLiBTaG93biBiZWxvdyBhcmUgdGhlIENUbWF4IHJlc2lkdWFscyAodGFrZW4gZnJvbSBhIG1vZGVsIG9mIENUbWF4IGFnYWluc3QgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkgcGxvdHRlZCBhZ2FpbnN0IHRoZSB0aW1lIHNwZW50IGluIGxhYiBiZWZvcmUgbWVhc3VyZW1lbnRzIHdlcmUgbWFkZS4gSW5kaXZpZHVhbCByZWdyZXNzaW9ucyBhcmUgc2hvd24gZm9yIHRoZSByZXNpZHVhbHMgYWdhaW5zdCBkYXlzIGluIGxhYiBmb3IgZWFjaCBjb2xsZWN0aW9uLiBXZSBjYW4gc2VlIGNsZWFybHkgdGhhdCB0aGVybWFsIGxpbWl0cyBhcmUgZmFpcmx5IHN0YWJsZSBvdmVyIHRpbWUuIAoKYGBge3Igc3VwcC1maWctY3RtYXgtdGltZS1pbi1sYWIsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KZ2dwbG90KGN0bWF4X3Jlc2lkcywgYWVzKHggPSBkYXlzX2luX2xhYiwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSwgZ3JvdXAgPSBjb2xsZWN0aW9uX2RhdGUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGFscGhhID0gMC41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMDo1KSkgKyAKICBsYWJzKHggPSAiRGF5cyBpbiBsYWIiLCAKICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIG1pc2MtQVJSLWxpbWl0cy1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQpmdWxsLm1vZGVsID0gbG1lNDo6bG1lcihkYXRhID0gbW9kZWxfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiBzZXggKyB0ZW1wX2NlbnQgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAoMSArIGRheXNfaW5fbGFiICsgdGVtcF9jZW50fHNwX25hbWUpKQoKY2FyOjpBbm92YShmdWxsLm1vZGVsKQoKZml4ZWQgPSBmaXhlZihmdWxsLm1vZGVsKQoKbW9kZWxfY29lZnMgPSBjb2VmZmljaWVudHMoZnVsbC5tb2RlbCkkYHNwX25hbWVgICU+JSAgCiAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJzcGVjaWVzIikgJT4lIAogIHNlcGFyYXRlKHNwZWNpZXMsIGludG8gPSBjKCJzcGVjaWVzIiksIHNlcCA9ICI6IikgJT4lIAogIHNlbGVjdChzcGVjaWVzLCAiaW50ZXJjZXB0IiA9ICIoSW50ZXJjZXB0KSIsIHRlbXBfY2VudCwgZGF5c19pbl9sYWIpCgpnZ3Bsb3QobW9kZWxfY29lZnMsIGFlcyh4ID0gaW50ZXJjZXB0LCB5ID0gdGVtcF9jZW50KSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc3BlY2llcyksCiAgICAgICAgICAgICBzaXplID0gNikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiU3BlY2llcyBJbnRlcmNlcHQiLCAKICAgICAgIHkgPSAiQVJSIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKCmBgYHtyIG1haW4tZmlnLUFSUi1zeW50aC1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQphcnJfY29tYmluZWQgPSBzeW50aF9hcnIgJT4lCiAgZmlsdGVyKG1lYXN1cmUgPT0gInVwcGVyIiAmIG1lYW5fbGltID4gMjApICU+JSAKICBzZWxlY3QoImdyb3VwIiA9IGdlbnVzLCBhcnIsIG1lYW5fbGltKSAlPiUgCiAgbXV0YXRlKCJkYXRhc2V0IiA9ICJzeW50aGVzaXMiKSAlPiUgCiAgYmluZF9yb3dzKAogICAgc2VsZWN0KG1vZGVsX2NvZWZzLCAiZ3JvdXAiID0gc3BlY2llcywgJ2FycicgPSB0ZW1wX2NlbnQsICdtZWFuX2xpbScgPSBpbnRlcmNlcHQpCiAgKSAlPiUgCiAgbXV0YXRlKGRhdGFzZXQgPSBpZl9lbHNlKGlzLm5hKGRhdGFzZXQpLCAibmV3IGRhdGEiLCAic3ludGhlc2lzIiksCiAgICAgICAgIGdyb3VwID0gZmN0X3Jlb3JkZXIoZ3JvdXAsIGFyciwgLmRlc2MgPSBUKSkKCgpnZ3Bsb3QoYXJyX2NvbWJpbmVkLCBhZXMoeCA9IG1lYW5fbGltLCB5ID0gYXJyKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIGNvbG91ciA9ICJncmV5MzAiKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihhcnJfY29tYmluZWQsIGRhdGFzZXQgIT0gIm5ldyBkYXRhIiksIAogICAgICAgICAgICAgc2l6ZSA9IDQsIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoYXJyX2NvbWJpbmVkLCBkYXRhc2V0ID09ICJuZXcgZGF0YSIpLAogICAgICAgICAgICAgYWVzKGNvbG91ciA9IGdyb3VwKSwgCiAgICAgICAgICAgICBzaXplID0gNCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiVGhlcm1hbCBMaW1pdCIsIAogICAgICAgeSA9ICJBUlIiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpgYGAKClRoZSB0ZXJtICJhY2NsaW1hdGlvbiByZXNwb25zZSByYXRpbyIgaXMgb2Z0ZW4gdXNlZCB0byBkZXNjcmliZSB0aGUgZWZmZWN0IG9mIHRlbXBlcmF0dXJlIG9uIHRoZXJtYWwgbGltaXRzLiBUaGUgQVJSIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIGNoYW5nZSBpbiB0aGVybWFsIGxpbWl0cyBwZXIgZGVncmVlIGNoYW5nZSBpbiBhY2NsaW1hdGlvbiB0ZW1wZXJhdHVyZS4gRm9yIG91ciBkYXRhLCB3ZSB3aWxsIGVzdGltYXRlIEFSUiBhcyB0aGUgc2xvcGUgb2YgQ1RtYXggYWdhaW5zdCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLiBUaGVzZSBzbG9wZXMgd2VyZSB0YWtlbiBmcm9tIGEgcmVncmVzc2lvbiBvZiBDVG1heCBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgYW5kIGJvZHkgc2l6ZS4gVHdvIGRpZmZlcmVudCBtb2RlbCB0eXBlcyB3ZXJlIHVzZWQsIGEgc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIGFuZCBhIG1peGVkIGVmZmVjdHMgbW9kZWwuIFRoZSBlc3RpbWF0ZWQgQVJSIHZhbHVlcyB3ZXJlIGdlbmVyYWxseSBoaWdobHkgc2ltaWxhciBiZXR3ZWVuIHRoZSBtb2RlbCB0eXBlcyB1c2VkLgoKYGBge3Igc3VwcC1maWctYXJyLWNvbXAtcGxvdCwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTAsIGluY2x1ZGUgPSBGfQpjb2VmX21vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIGZpbHRlcihuKCkgPiAzICYgIXN0cl9kZXRlY3Qoc3BfbmFtZSwgcGF0dGVybiA9ICJraW5kdGkiKSkgCgpjb2VmX24gPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIGZpbHRlcihuKCkgPiA1KSAlPiUgCiAgc3VtbWFyaXNlKHNhbXBsZV9uID0gbigpLCAKICAgICAgICAgICAgbWVhbl9jdG1heCA9IG1lYW4oY3RtYXgpKQoKQVJSX3ZhbHMgPSBjb2VmX21vZGVsX2RhdGEgJT4lIAogIGRvKGJyb29tOjp0aWR5KGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc2l6ZSwgZGF0YSA9IC4pKSkgJT4lIAogIGZpbHRlcih0ZXJtID09ICJjb2xsZWN0aW9uX3RlbXAiKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIHNleCwgIkFSUiIgPSBlc3RpbWF0ZSwgc3RkLmVycm9yKSAlPiUgCiAgYXJyYW5nZShBUlIpICU+JSAKICBpbm5lcl9qb2luKGNvZWZfbiwgYnkgPSBjKCJzcF9uYW1lIiwgInNleCIpKQoKQVJSX3ZhbHMgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAKICAgICAgICAgIkdyb3VwIiA9IHNleCwgCiAgICAgICAgICJOIiA9IHNhbXBsZV9uLAogICAgICAgICBBUlIsIAogICAgICAgICAiRXJyb3IiID0gc3RkLmVycm9yKSAlPiUgCiAga25pdHI6OmthYmxlKCkKCm1sZV9jb2VmcyA9IGNvZWZmaWNpZW50cyhmdWxsLm1vZGVsKSRgc3BfbmFtZWAgJT4lIAogIG11dGF0ZSgiZ3JvdXAiID0gcm93bmFtZXMoLikpICU+JSAKICBzZWxlY3QoZ3JvdXAsICJpbnRlcmNlcHQiID0gIihJbnRlcmNlcHQpIiwgIkFSUiIgPSB0ZW1wX2NlbnQpICU+JSAKICByZW1vdmVfcm93bmFtZXMoKQoKbWxlX0FSUiA9IG1sZV9jb2VmcyAlPiUgIAogIHNlbGVjdChzcF9uYW1lID0gZ3JvdXAsIEFSUikgJT4lIAogIG11dGF0ZSgibW9kZWwiID0gIm1peGVkIGVmZmVjdHMiKSAgJT4lIAogIGlubmVyX2pvaW4oY29lZl9uLCBieSA9IGMoInNwX25hbWUiKSkKCkFSUl9jb21wID0gYmluZF9yb3dzKG1sZV9BUlIsIAogICAgICAgICAgICAgICAgICAgICBtdXRhdGUoQVJSX3ZhbHMsICJtb2RlbCIgPSAibGluZWFyIikpCgpBUlJfY29tcCAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbW9kZWwsIHkgPSBBUlIsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfZ3JpZChzcF9uYW1lfnNleCkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAwLjUsIDEpKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCgpgYGAKCiMjIyBTZXggYW5kIHN0YWdlIHZhcmlhdGlvbiBpbiB0aGVybWFsIGxpbWl0cyAKUHJldmlvdXMgc2VjdGlvbnMgaGF2ZSBnZW5lcmFsbHkgbHVtcGVkIGp1dmVuaWxlLCBmZW1hbGUsIGFuZCBtYWxlIGluZGl2aWR1YWxzIHRvZ2V0aGVyLiBUaGVyZSBtYXkgYmUgaW1wb3J0YW50IHN0YWdlLSBvciBzZXgtc3BlY2lmaWMgZGlmZmVyZW5jZXMgaW4gQ1RtYXggdGhvdWdoLiBGb3Igc2V2ZXJhbCBzcGVjaWVzLCB3ZSBoYXZlIG1lYXN1cmVtZW50cyBmb3IgaW5kaXZpZHVhbHMgaW4gZGlmZmVyZW50IHN0YWdlcyBvciBvZiBkaWZmZXJlbnQgc2V4ZXMuIAoKYGBge3Igc2V4LXN0YWdlLXRhYmxlfQpzZXhfc2FtcGxlX3NpemVzID0gY3RtYXhfcmVzaWRzICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgIAogIHN1bW1hcmlzZShudW0gPSBuKCkpICU+JSAgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IHNwX25hbWUsCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNleCwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBudW0sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJKdXZlbmlsZSIgPSBqdXZlbmlsZSwgIkZlbWFsZSIgPSBmZW1hbGUsICJNYWxlIiA9IG1hbGUpCgprbml0cjo6a2FibGUoc2V4X3NhbXBsZV9zaXplcywgYWxpZ24gPSAiYyIpCmBgYAoKVGhlIGZlbWFsZS1tYWxlIGFuZCBmZW1hbGUtanV2ZW5pbGUgY29tcGFyaXNvbnMgc2hvdyB0aGF0IHRoZXJlIGFyZSBnZW5lcmFsbHkgbm8gZGlmZmVyZW5jZXMgaW4gdGhlcm1hbCBsaW1pdHMgYmV0d2VlbiB0aGVzZSBncm91cHMuIAoKYGBge3Igc3VwcC1maWctY3RtYXgtc2V4LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIE1hbGUgPiAwLCBGZW1hbGUgPiAwKSRTcGVjaWVzICYgCiAgICAgICAgICAgc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZXgsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoZWlnaHQgPSAwLCB3aWR0aCA9IDAuMDUpKSArICAKICBsYWJzKHggPSAiU2V4IiwgCiAgICAgICB5ID0gIkNUbWF4IFJlc2lkdWFscyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyIHN1cHAtZmlnLWN0bWF4LXN0YWdlLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIEp1dmVuaWxlID4gMCAmIEZlbWFsZSA+IDApJFNwZWNpZXMgJiAKICAgICAgICAgICBzZXggIT0gIm1hbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lLCBncm91cCA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaGVpZ2h0ID0gMCwgd2lkdGggPSAwLjA1KSkgKyAgCiAgbGFicyh4ID0gIlNleCIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyIHRyYWl0LXZhcmlhbmNlLWNvbGwtdGVtcCwgaW5jbHVkZSA9IEZ9CiMgCiMgR2l2ZW4gdGhlIGxvbmcgZ2VuZXJhdGlvbiB0aW1lcyBvZiB0aGVzZSBjb3BlcG9kcywgZGVjcmVhc2VzIGluIHRyYWl0IHZhcmlhbmNlIG1heSBpbmRpY2F0ZSBzZWxlY3Rpb24gb3ZlciB0aGUgc2Vhc29uYWwgY3ljbGUuIFNob3duIGJlbG93IGFyZSB0aGUgdmFyaWFuY2UgaW4gb2JzZXJ2ZWQgQ1RtYXggYW5kIHNpemUsIHBsb3R0ZWQgYWdhaW5zdCBjb2xsZWN0aW9uIGRhdGUuIFZhcmlhbmNlIGRlY3JlYXNlcyBpbiAqU2tpc3RvZGlhcHRvbXVzKiwgYnV0IHRoaXMgcGF0dGVybiBpcyBkcml2ZW4gYnkgYSBzaW5nbGUgY29sbGVjdGlvbiB3aXRoIGhpZ2ggdmFyaWFuY2UgZWFybHkgaW4gdGhlIHllYXIuIFNpemUgdmFyaWFuY2UgaW5jcmVhc2VzIHNsaWdodGx5IGluICpTa2lzdG9kaWFwdG9tdXMqLiBWYXJpYW5jZSBpbiBib3RoIENUbWF4IGFuZCBzaXplIGlzIGZhaXJseSBjb25zdGFudCBpbiAqTGVwdG9kaWFwdG9tdXMgbWludXR1cyosIHRoZSBvbmx5IG90aGVyIHNwZWNpZXMgY29sbGVjdGVkIGFjcm9zcyB0aGUgZW50aXJlIHNldCBvZiBzYW1wbGVzIHRodXMgZmFyLiAKIyAKIyBnZ3Bsb3QoZHJvcF9uYShhZHVsdF9zdW1tYXJpZXMsIGN0bWF4X3ZhciksIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKIyAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBzY2FsZXMgPSAiZnJlZV95IikgKyAKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiMgICBnZW9tX3Ntb290aChzZSA9IEYpICsgCiMgICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAojICAgICAgICB5ID0gIkNUbWF4IFZhcmlhbmNlIikgKyAKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIAojIGdncGxvdChkcm9wX25hKGFkdWx0X3N1bW1hcmllcywgc2l6ZV92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemVfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKIyAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAojICAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKIyAgIGdlb21fc21vb3RoKHNlID0gRikgKyAKIyAgIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiMgICAgICAgIHkgPSAiU2l6ZSBWYXJpYW5jZSIpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKIyAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgoKIyMjIFRyYWl0IENvcnJlbGF0aW9ucyBhbmQgVHJhZGUtb2ZmcwoKQSByZWxhdGlvbnNoaXAgYmV0d2VlbiBzaXplIGFuZCB1cHBlciB0aGVybWFsIGxpbWl0cyBoYXMgYmVlbiBzdWdnZXN0ZWQgaW4gYSB3aWRlIHJhbmdlIG9mIG90aGVyIHRheGEuIFNob3duIGJlbG93IGFyZSB0aGUgbWVhc3VyZWQgdXBwZXIgdGhlcm1hbCBsaW1pdHMgcGxvdHRlZCBhZ2FpbnN0IHByb3NvbWUgbGVuZ3RoLiBUaGUgb3ZlcmFsbCByZWxhdGlvbnNoaXAgKGluY2x1c2l2ZSBvZiBhbGwgc3BlY2llcykgaXMgc2hvd24gYXMgdGhlIGJsYWNrIGxpbmUgaW4gdGhlIGJhY2tncm91bmQuIFJlZ3Jlc3Npb25zIGZvciBlYWNoIGluZGl2aWR1YWwgc3BlY2llcyBhcmUgYWxzbyBzaG93bi4gQWNyb3NzIHRoZSBlbnRpcmUgYXNzZW1ibGFnZSwgdGhlcmUgaXMgYSBzdHJvbmcgZGVjcmVhc2UgaW4gdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIHNpemUuICAKCmBgYHtyIG1pc2MtY3RtYXgtc2l6ZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTd9CgpmdWxsX2RhdGEgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgIAogIGdncGxvdCggYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogICAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZ1bGxfZGF0YSwgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpLAogICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICAgICAgICAgICAgIGNvbG91ciA9ImJsYWNrIiwgCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMi41KSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmBgYAoKU2hvd24gaGVyZSBpcyB0aGUgcmVsYXRpb25zaGlwIGZvciBlYWNoIHNwZWNpZXMgaW5kaXZpZHVhbGx5LiAKCmBgYHtyIG1pc2MtaW5kLXNwLWN0bWF4LXNpemUsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTZ9CmZ1bGxfZGF0YSAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIGZpbHRlcihuKCkgPjIpICU+JSBmaWx0ZXIoIXN0cl9kZXRlY3Qoc3BfbmFtZSwgcGF0dGVybiA9ICJraW5kdGkiKSkgJT4lIAogIGdncGxvdCggYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWVhbiBzaXplIGFuZCBtZWFuIHRoZXJtYWwgbGltaXRzIGZvciBmZW1hbGVzIG9mIGVhY2ggc3BlY2llcy4gV2Ugc2VlIHRoYXQgbGFyZ2VyIHNwZWNpZXMgd2l0aGluIHRoZSBjb21tdW5pdHkgdGVuZCB0byBoYXZlIGEgbG93ZXIgdGhlcm1hbCBsaW1pdCB0aGFuIHNtYWxsZXIgc3BlY2llcy4gCgpgYGB7ciBtYWluLWZpZy1tZWFuLWN0bWF4LW1lYW4tc2l6ZS1wbG90LCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQpmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIHN1bW1hcml6ZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCwgbmEucm0gPSBUKSwKICAgICAgICAgICAgbWVhbl9zaXplID0gbWVhbihzaXplLCBuYS5ybSA9IFQpKSAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3NpemUsIHkgPSBtZWFuX2N0bWF4KSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIsIGNvbG91ciA9ICJibGFjayIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc3BfbmFtZSwgc2hhcGUgPSBzZXgpLAogICAgICAgICAgICAgc2l6ZSA9IDUpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCmBgYHtyIGN0bWF4cmVzaWRzLXNpemUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBpbmNsdWRlID0gRn0KY3RtYXhfcmVzaWRzICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemVfcmVzaWRzLCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpTaG93biBoZXJlIGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBmZWN1bmRpdHkgYW5kIHNpemUsIHNob3dpbmcgdGhlIGNsYXNzaWMgcGF0dGVybiBvZiBpbmNyZWFzaW5nIGVnZyBwcm9kdWN0aW9uIHdpdGggaW5jcmVhc2luZyBzaXplLiAKCmBgYHtyIGZlY3VuZGl0eS1zaXplfQpzaXplX2ZlY3VuZF9wbG90ID0gY3RtYXhfcmVzaWRzICU+JSAgCiAgZHJvcF9uYShmZWN1bmRpdHkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gIlByb3NvbWUgbGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiRmVjdW5kaXR5ICgjIEVnZ3MpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCkluZGl2aWR1YWxzIG1heSBhbHNvIGFsbG9jYXRlIGVuZXJneSB0byBkaWZmZXJlbnQgZml0bmVzcyByZWxhdGVkIHRyYWl0cywgcHJpb3JpdGl6aW5nIHJlcHJvZHVjdGl2ZSBvdXRwdXQgb3ZlciBlbnZpcm9ubWVudGFsIHRvbGVyYW5jZSwgZm9yIGV4YW1wbGUuIFNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBDVG1heCByZXNpZHVhbHMgKGFnYWluLCBjb250cm9sbGluZyBmb3IgdGhlIGVmZmVjdHMgb2YgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkgYWdhaW5zdCBmZWN1bmRpdHkuIFdlIGNhbiBzZWUgY2xlYXJseSB0aGF0IGluZGl2aWR1YWxzIHdpdGggaW5jcmVhc2VkIGZlY3VuZGl0eSBhcmUgbm90IGRlY3JlYXNpbmcgdGhlcm1hbCBsaW1pdHMsIHN1Z2dlc3RpbmcgdGhhdCB0aGVyZSBpcyBubyBlbmVyZ2V0aWMgdHJhZGUtb2ZmIGJldHdlZW4gdGhlc2UgdHJhaXRzLiAKYGBge3IsIG1haW4tZmlnLWZlY3VuZGl0eS1wbG90cywgZmlnLndpZHRoPTguNSwgZmlnLmhlaWdodD0xMH0KY3RtYXhfZmVjdW5kX3Bsb3QgPSBjdG1heF9yZXNpZHMgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHJlc2lkcywgeSA9IGZlY3VuZGl0eV9yZXNpZHMsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuNSkgKyAKICBsYWJzKHggPSAiQ1RtYXggUmVzaWR1YWxzIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSBSZXNpZHVhbHMiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2Uoc2l6ZV9mZWN1bmRfcGxvdCwgY3RtYXhfZmVjdW5kX3Bsb3QsIG5jb2wgPSAxLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gInJpZ2h0IikKYGBgCgojIyBPdGhlciBwYXR0ZXJucyBpbiB2YXJpYXRpb24gCgoqTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyogaXMgdGhlIG1vc3QgYWJ1bmRhbnQgc3BlY2llcyBkdXJpbmcgdGhlIHdpbnRlci4gVGhlcmUgd2FzIGEgbGFyZ2Ugc2hpZnQgaW4gdGhlIHNpemUgb2YgbWF0dXJlIGZlbWFsZXMgdG93YXJkcyB0aGUgZW5kIG9mIERlY2VtYmVyLiBUaGVzZSBsYXJnZSBhbmQgc21hbGwgaW5kaXZpZHVhbHMgYXJlIHRoZSBzYW1lIHNwZWNpZXMgKGNvbmZpcm1lZCB2aWEgQ09JIHNlcXVlbmNpbmcpLCBzdWdnZXN0aW5nIHRoaXMgc2hpZnQgbWF5IHJlZmxlY3QgYSB0cmFuc2l0aW9uIGZyb20gb25lIGdlbmVyYXRpb24gdG8gYW5vdGhlciBhbmQgdGhhdCwgdW5saWtlIGluIG1hbnkgb3RoZXIgbGFrZXMsIHRoZXJlIGFyZSB0d28gZ2VuZXJhdGlvbnMgb2YgKkwuIHNpY2lsaXMqIHBlciB5ZWFyIGluIExha2UgQ2hhbXBsYWluLiBUaGlzIHNpemUgZGlmZmVyZW5jZSBtYXkgYmUgY2F1c2VkIGJ5IGRpZmZlcmVuY2VzIGluIHRoZSBkZXZlbG9wbWVudGFsIGVudmlyb25tZW50cy4gRm9yIGV4YW1wbGUsIGluZGl2aWR1YWxzIGRldmVsb3BpbmcgaW4gSmFudWFyeSBncm93IHVwIGF0IHZlcnkgbG93IHRlbXBlcmF0dXJlcywgYW5kIHRoZXJlZm9yZSBtYXkgcmVhY2ggbGFyZ2VyIHNpemVzLiBUaGVzZSBpbmRpdmlkdWFscyBvdmVyc3VtbWVyIGluIGRlZXAgd2F0ZXJzLCB0aGVuIHJlLWVtZXJnZSBpbiBPY3RvYmVyIGFuZCBwcm9kdWNlIGEgbmV3IGdlbmVyYXRpb24uIFdhdGVyIHRlbXBlcmF0dXJlcyBhcmUgc3RpbGwgZmFpcmx5IGhpZ2ggdGhyb3VnaCBOb3ZlbWJlciwgd2hpY2ggcmVzdWx0cyBpbiBhIGdlbmVyYXRpb24gb2Ygc21hbGxlciBpbmRpdmlkdWFscywgd2hpY2ggbWF0dXJlIGluIHRpbWUgdG8gcHJvZHVjZSBhIG5ldyBnZW5lcmF0aW9uIGluIEphbnVhcnkuIAoKU2hvd24gYmVsb3cgaXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwYWlyd2lzZSBkaXN0YW5jZXMgYmV0d2VlbiBDT0kgc2VxdWVuY2VzIG9mIGxhcmdlIGFuZCBzbWFsbCBtb3JwaHMuIERpc3RhbmNlcyBpbiBib3RoIHdpdGhpbi0gYW5kIGFjcm9zcy1tb3JwaCBjb21wYXJpc29ucyBhcmUgc21hbGwuIAoKYGBge3Igc3VwcC1maWctbHNpYy1nZW5kaWZmfQppbmRfZGlzdCA9IGFwZTo6ZGlzdC5kbmEoc2ljX2RuYWJpbiwgbW9kZWwgPSAicmF3IikgJT4lIGFzLm1hdHJpeCAlPiUgCiAgYXNfdGliYmxlKCkgJT4lCiAgbXV0YXRlKCJpbmQxIiA9IGNvbG5hbWVzKC4pKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKC1pbmQxLCBuYW1lc190byA9ICJpbmQyIiwgdmFsdWVzX3RvID0gImRpc3QiKSAlPiUKICBtdXRhdGUoaW5kMSA9IGZhY3RvcihpbmQxKSwKICAgICAgICAgaW5kMiA9IGZhY3RvcihpbmQyKSkgJT4lIAogIGZpbHRlcighKGluZDEgPT0gInNvcmUxIiB8IGluZDIgPT0gInNvcmUxIikpICU+JSAKICBtdXRhdGUoCiAgICBpbmQxID0gY2FzZV93aGVuKAogICAgICBpbmQxID09ICJTMSIgfiAic21hbGwxIiwKICAgICAgaW5kMSA9PSAiUzMiIH4gInNtYWxsMyIsCiAgICAgIGluZDEgPT0gImxzaWMzIiB+ICJzbWFsbDQiLAogICAgICBpbmQxID09ICJsc2ljNSIgfiAic21hbGw2IiwKICAgICAgaW5kMSA9PSAibHNpYzkiIH4gInNtYWxsOCIsCiAgICAgIGluZDEgPT0gImxzaWMxMCIgfiAic21hbGw5IiwKICAgICAgaW5kMSA9PSAibHNpYzExIiB+ICJzbWFsbDEwIiwKICAgICAgaW5kMSA9PSAiTDEiIH4gImxhcmdlMSIsCiAgICAgIGluZDEgPT0gIkwyIiB+ICJsYXJnZTIiLAogICAgICBpbmQxID09ICJMMyIgfiAibGFyZ2UzIiwKICAgICAgaW5kMSA9PSAibHNpYzEiIH4gImxhcmdlNCIsCiAgICAgIGluZDEgPT0gImxzaWMyIiB+ICJsYXJnZTUiLAogICAgICBpbmQxID09ICJsc2ljNyIgfiAibGFyZ2U2IiwKICAgICAgaW5kMSA9PSAibHNpYzgiIH4gImxhcmdlNyIpLAogICAgaW5kMiA9IGNhc2Vfd2hlbigKICAgICAgaW5kMiA9PSAiUzEiIH4gInNtYWxsMSIsCiAgICAgIGluZDIgPT0gIlMzIiB+ICJzbWFsbDMiLAogICAgICBpbmQyID09ICJsc2ljMyIgfiAic21hbGw0IiwKICAgICAgaW5kMiA9PSAibHNpYzUiIH4gInNtYWxsNiIsCiAgICAgIGluZDIgPT0gImxzaWM5IiB+ICJzbWFsbDgiLAogICAgICBpbmQyID09ICJsc2ljMTAiIH4gInNtYWxsOSIsCiAgICAgIGluZDIgPT0gImxzaWMxMSIgfiAic21hbGwxMCIsCiAgICAgIGluZDIgPT0gIkwxIiB+ICJsYXJnZTEiLAogICAgICBpbmQyID09ICJMMiIgfiAibGFyZ2UyIiwKICAgICAgaW5kMiA9PSAiTDMiIH4gImxhcmdlMyIsCiAgICAgIGluZDIgPT0gImxzaWMxIiB+ICJsYXJnZTQiLAogICAgICBpbmQyID09ICJsc2ljMiIgfiAibGFyZ2U1IiwKICAgICAgaW5kMiA9PSAibHNpYzciIH4gImxhcmdlNiIsCiAgICAgIGluZDIgPT0gImxzaWM4IiB+ICJsYXJnZTciKSwKICAgICdjb21wYXJpc29uJyA9IGNhc2Vfd2hlbigKICAgICAgc3RyX2RldGVjdChpbmQxLCBwYXR0ZXJuID0gImxhcmdlIikgJiBzdHJfZGV0ZWN0KGluZDIsIHBhdHRlcm4gPSAibGFyZ2UiKSB+ICJ3aXRoaW4iLAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAic21hbGwiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJzbWFsbCIpIH4gIndpdGhpbiIsIAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAibGFyZ2UiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJzbWFsbCIpIH4gImFjcm9zcyIsCiAgICAgIHN0cl9kZXRlY3QoaW5kMSwgcGF0dGVybiA9ICJzbWFsbCIpICYgc3RyX2RldGVjdChpbmQyLCBwYXR0ZXJuID0gImxhcmdlIikgfiAiYWNyb3NzIgogICAgKSkgCgpnZ3Bsb3QoaW5kX2Rpc3QsIGFlcyhkaXN0LCBmaWxsID0gY29tcGFyaXNvbikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDA1KSArIAogIGxhYnMoeCA9ICJEaXN0YW5jZSIpICsgCiAgdGhlbWVfbWF0dCgpCmBgYAoKCmBgYHtyIHN1cHAtZmlnLWxzaWMtbW9ycGgtc2l6ZX0KZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNwX25hbWUgPT0gIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgbXV0YXRlKHNpemVfY2VudGVyID0gc2NhbGUoc2l6ZSwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSkgJT4lIAogIGdncGxvdChhZXMoeSA9IGZhY3Rvcihjb2xsZWN0aW9uX2RhdGUpLCB4ID0gc2l6ZSwgZmlsbCA9IGNvbGxlY3Rpb25fdGVtcCkpICsgCiAgZmFjZXRfd3JhcChzZXh+LikgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDAuMDQpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC44OSkgKyAKICBsYWJzKHggPSAiU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiRGF0ZSIsIAogICAgICAgZmlsbCA9ICJDb2xsLiBUZW1wLiAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQpgYGAKCmBgYHtyIGluY2x1ZGUgPSBGfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmYWN0b3IoY29sbGVjdGlvbl9kYXRlKSwgeCA9IHNpemUsIGZpbGwgPSBjb2xsZWN0aW9uX3RlbXApKSArIAogIGZhY2V0X3dyYXAoc2V4fi4pICsgCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhiYW5kd2lkdGggPSAwLjA0KSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuNjkpICsgCiAgbGFicyh4ID0gIlNpemUgKG1tKSIsCiAgICAgICB5ID0gIkRhdGUiLCAKICAgICAgIGZpbGwgPSAiQ29sbC4gVGVtcC4gKMKwQykiKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLjUsMC45KSkgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKIyMgRGlzdHJpYnV0aW9uIExhZyBOb24tTGluZWFyIE1vZGVsIChETE5NIGFwcHJvYWNoKSAKCkRpc3RyaWJ1dGVkIGxhZyBtb2RlbHMgZXhhbWluZSBhIHJlc3BvbnNlIHZhcmlhYmxlLCBtZWFzdXJlZCBhdCBtdWx0aXBsZSB0aW1lIHBvaW50cywgYXMgYSBmdW5jdGlvbiBvZiB0aGUgbGFnZ2VkIG9jY3VycmVuY2Ugb2Ygc29tZSBwcmVkaWN0b3IgdmFyaWFibGUgKHJlc3BvbnNlIHkgYXQgdGltZSB0IGFzIGEgZnVuY3Rpb24gb2YgcHJlZGl0b3IgeCh0LWxhZykuIFRoaXMgbWV0aG9kIHV0aWxpemVzIGEgYmktZGltZW5zaW9uYWwgZG9zZS1sYWctcmVzcG9uc2UgZnVuY3Rpb24sIHdoaWNoIGVzc2VudGlhbGx5IGV4YW1pbmVzIG5vdCBvbmx5IHRoZSBkb3NlIGVmZmVjdCwgYnV0IHRoZSBlZmZlY3Qgb2YgdGhlIHRpbWluZyBvZiB0aGUgZG9zZS4gCgoKYGBge3IgY29tcGlsaW5nX3RlbXBfbGFnc30KIyBSdW4gdGhpcyBjb2RlLCBzYXZlIHRoZSBwcm9kdWN0LCBhbmQgdGhlbiBqdXN0IHJlYWQgaW4gdGhlIHRlbXAgbGFnIGRhdGEgb2JqZWN0LiBUYWtlcyB0b28gbG9uZyB0byBydW4gZWFjaCB0aW1lIHRoaXMgZG9jdW1lbnQgaXMga25pdC4gCgojIGxhZ190ZW1wcyA9IHRlbXBfZGF0YSAlPiUKIyAgIGdyb3VwX2J5KGRhdGUsIGhvdXIpICU+JQojICAgc3VtbWFyaXplKCJtZWFuX3RlbXAiID0gbWVhbih0ZW1wLCBuYS5ybSA9IFQpKSAlPiUKIyAgIHVuZ3JvdXAoKSAlPiUKIyAgIG11dGF0ZShwb2ludF9udW0gPSByb3dfbnVtYmVyKCkpCiMgCiMgdW5pcV9kYXlzID0gbGVuZ3RoKHVuaXF1ZShsYWdfdGVtcHMkZGF0ZSkpCiMgCiMgZyA9IGdhbShtZWFuX3RlbXAgfiBzKHBvaW50X251bSwgYnM9ImNyIiwgaz11bmlxX2RheXMgKyAxMCksCiMgICAgIG1ldGhvZCA9ICJSRU1MIiwKIyAgICAgZGF0YSA9IGxhZ190ZW1wcykKIyAKIyBwb2ludHMgPSBzZXEoMSwgbnJvdyhsYWdfdGVtcHMpLCBsZW5ndGgub3V0ID0gbGVuZ3RoKGxhZ190ZW1wcyRob3VyKSkKIyAKIyBkZi5yZXMgPSBkZi5yZXNpZHVhbChnKQojIAojIHByZWRfdGVtcHMgPSBwcmVkaWN0KGcsIG5ld2RhdGEgPSBsYWdfdGVtcHMsIHR5cGUgPSAicmVzcG9uc2UiLCBzZS5maXQgPSBUUlVFKQojIAojIGxhZ190ZW1wcyA9IGxhZ190ZW1wcyAlPiUKIyAgIG11dGF0ZSh0cmVuZF9UID0gcHJlZF90ZW1wcyRmaXQsCiMgICAgICAgICAgdHJlbmRfc2UgPSBwcmVkX3RlbXBzJHNlLmZpdCwKIyAgICAgICAgICB0ZW1wX2RpZmYgPSBtZWFuX3RlbXAgLSB0cmVuZF9UKQojIAojIHdyaXRlLmNzdihsYWdfdGVtcHMsIGZpbGUgPSAiLi9PdXRwdXQvRGF0YS9sYWdfdGVtcHMuY3N2Iiwgcm93Lm5hbWVzID0gRikKCmBgYAoKYGBge3IgZ2VuZXJhbC1yZWxhdGlvbnNoaXB9IAoKZGxubV9kYXRhID0gZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgYygKICAgICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwKICAgICJMZXB0b2RpYXB0b211cyBtaW51dHVzIiwKICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiCiAgKSkgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCwgc3BfbmFtZSwgY3RtYXgpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCwgc3BfbmFtZSkgJT4lICAKICBzdW1tYXJpc2UobWVhbl9jdG1heCA9IG1lYW4oY3RtYXgsIG5hLnJtID0gVCksCiAgICAgICAgICAgIHNhbXBsZSA9IG4oKSkKCnRlbXBfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wLCBuYS5ybSA9IFQpKSAlPiUgCiAgcmlnaHRfam9pbihkbG5tX2RhdGEsIGJ5ID0gam9pbl9ieSgiZGF0ZSIgPT0gImNvbGxlY3Rpb25fZGF0ZSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbWF4X3RlbXAsIHkgPSBtZWFuX2N0bWF4KSkgKyAKICBmYWNldF93cmFwKC5+c3BfbmFtZSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAiZ2FtIikgKyAKICBnZW9tX3BvaW50KCkgKyAKICBsYWJzKHggPSAiTWF4IERhaWx5IFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWVhbiBDVG1heCAowrBDKSIpICsgCnRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKYGBgCgpgYGB7ciBzdXBwLWZpZy1kbG5tLXBsb3R9CgpzcF9saXN0ID0gdW5pcXVlKGRsbm1fZGF0YSRzcF9uYW1lKQoKZm9yKGxhZ19zcGVjaWVzIGluIHNwX2xpc3QpewogIAogIGRsbm1fZGF0YV9zcCA9IGRsbm1fZGF0YSAlPiUgCiAgICBmaWx0ZXIoc3BfbmFtZSA9PSBsYWdfc3BlY2llcykKICAKICAjIFdlIG5lZWQgdG8gZXN0aW1hdGUgYSBtYXRyaXggb2YgZXhwb3N1cmUgaGlzdG9yaWVzIGZvciBlYWNoIG9ic2VydmF0aW9uLiBUaGlzIGNvbnRhaW5zIHRoZSBzZXJpZXMgb2YgZXhwb3N1cmVzIGF0IGVhY2ggbGFnIChsKSBmb3IgZWFjaCBvZiB0aGUgbiBvYnNlcnZhdGlvbnMsIGNvbnN0cmFpbmVkIGJldHdlZW4gbDAgKG1pbmltdW0gbGFnKSBhbmQgTCAobWF4IGxhZykuIAoKZGF0ZXMgPSBkbG5tX2RhdGFfc3AkY29sbGVjdGlvbl9kYXRlICMgRm9yIGVhY2ggb2YgdGhlc2UgZGF0ZXMsIG1ha2UgYSB2ZWN0b3Igb2YgdGhlIHBhc3QgMzAgZGF5cyAoaW5jbHVkaW5nIHRoZSBkYXkgb2YgY29sbGVjdGlvbikuIE5PVEU6IERvbid0IHVzZSAndW5pcXVlJyBkYXRlcyBoZXJlIHNpbmNlIHNvbWUgY29sbGVjdGlvbnMgaGFkIG11bHRpcGxlIHNwZWNpZXMKCmV4cF9oaXN0X3ogPSBkYXRhLmZyYW1lKCkKZXhwX2hpc3RfdHJlbmQgPSBkYXRhLmZyYW1lKCkKCmZvcihkIGluIGRhdGVzKXsKICAKICBoaXN0b3J5ID0gbGFnX3RlbXBzICU+JSAKICAgIGZpbHRlcihkYXRlIDw9IGQgJiBkYXRlID4gZCAtIDEwKSAlPiUgCiAgICBhcnJhbmdlKGRlc2MoZGF0ZSksIGRlc2MoaG91cikpICU+JSAKICAgIG11dGF0ZShsYWcgPSByb3dfbnVtYmVyKCkgLSAxKSAlPiUgCiAgICBzZWxlY3QobGFnLCBtZWFuX3RlbXAsIHRlbXBfZGlmZikKICAKICB6X3ZlYyA9IHNjYWxlKGhpc3RvcnkkbWVhbl90ZW1wKVssMV0KICBuYW1lcyh6X3ZlYykgPSBoaXN0b3J5JGxhZwogIAogIHRyZW5kX3ZlYyA9IGhpc3RvcnkkdGVtcF9kaWZmCiAgbmFtZXModHJlbmRfdmVjKSA9IGhpc3RvcnkkbGFnCgogIGV4cF9oaXN0X3ogPSBiaW5kX3Jvd3MoZXhwX2hpc3Rfeiwgel92ZWMpCiAgZXhwX2hpc3RfdHJlbmQgPSBiaW5kX3Jvd3MoZXhwX2hpc3RfdHJlbmQsIHRyZW5kX3ZlYykKICAKfQoKI3ByaW50KG1heChleHBfaGlzdF90cmVuZCwgbmEucm0gPSBUKSkKCiMgVGhlIGNyb3NzLWJhc2lzIGZ1bmN0aW9uIGZyb20gZGxubSB3aWxsIHVzZSB0aGUgY2xhc3Mgb2YgdGhlIHggcGFyYW1ldGVyIHRvIGRldGVybWluZSB3aGF0IHRvIGRvLiBJbiBvdXIgY2FzZSwgd2UgbmVlZCB0byBwcm92aWRlIGl0IHdpdGggdGhlIG1hdHJpeCBvZiBleHBvc3VyZSBoaXN0b3JpZXMgZm9yIHJlYWNoIG9ic2VydmF0aW9uIChyb3cpIGFuZCBsYWcgKGNvbHVtbikuIAoKY2JfdGVtcHMgPSBjcm9zc2Jhc2lzKGV4cF9oaXN0X3RyZW5kLCBsYWcgPSBjKDAsZGltKGV4cF9oaXN0X3RyZW5kKVsyXS0xKSwgCiAgICAgICAgICAgICAgICAgICAgICBhcmd2YXIgPWxpc3QoZnVuPSJjciIsZGY9MyksIAogICAgICAgICAgICAgICAgICAgICAgYXJnbGFnPWxpc3QoZnVuPSJjciIsZGY9MyxpbnRlcmNlcHQ9VCkpCgojc3VtbWFyeShjYl90ZW1wcykKCnBlbmFsaXplZF9tYXQgPC0gY2JQZW4oY2JfdGVtcHMpCgojZml0dGluZyBHQU0KbGFnLmdhbSA9IGdhbShkYXRhID0gZGxubV9kYXRhX3NwLCAKICAgICAgICAgICAgICBtZWFuX2N0bWF4IH4gY2JfdGVtcHMgKyBjb2xsZWN0aW9uX3RlbXAsIAogICAgICAgICAgICAgIG1ldGhvZCA9ICJHQ1YuQ3AiLAogICAgICAgICAgICAgIHBhcmFQZW49bGlzdChjYl90ZW1wcz1wZW5hbGl6ZWRfbWF0KSkKCiMgc3VtbWFyeShsYWcuZ2FtKQojIEFJQyhsYWcuZ2FtKQoKI2VzdGltYXRpb24gb2YgZXhwb3N1cmVzIGVmZmVjdHMKCiNkZWZhdWx0IHBsb3RzCnByZWRfZ2FtX1pzPC1jcm9zc3ByZWQoY2JfdGVtcHMsIGxhZy5nYW0sIAogICAgICAgICAgICAgICAgICAgICAgIGN1bXVsPUYsIGNlbj0wLCBjaS5sZXZlbCA9IDAuOTUsCiAgICAgICAgICAgICAgICAgICAgICAgYXQ9c2VxKC00LDQsIDAuMSkpCgpwbG90KHByZWRfZ2FtX1pzLCAiY29udG91ciIpCiMgCiMgcGxvdChwcmVkX2dhbV9acywgYm9yZGVyID0gMiwgY3VtdWw9RiwKIyAgICAgICB0aGV0YT0xMTAscGhpPTIwLGx0aGV0YT0tODApCgpwbG90KHByZWRfZ2FtX1pzLCAic2xpY2VzIiwKICAgICB2YXIgPSBjKDMsLTMpLAogICAgIGxhZyA9IGMoMSwyMDApLAogICAgIGNvbCA9IDIpCgp9CgoKCmBgYAoKCmBgYHtyfQppZihwcmVkaWN0X3Z1bG4gPT0gRil7CiAga25pdHI6OmtuaXRfZXhpdCgpCn0KYGBgCgoKIyMgUHJlZGljdGluZyBWdWxuZXJhYmlsaXR5IApVc2luZyB0aGUgb2JzZXJ2ZWQgdGhlcm1hbCBsaW1pdCBkYXRhLCB3ZSBjYW4gcHJvZHVjZSBhIGhpbmRjYXN0IG9mIHRoZXJtYWwgc3RyZXNzIGZvciBMYWtlIENoYW1wbGFpbiBjb3BlcG9kcy4gRm9yIHRoZXNlIGluaXRpYWwgYXNzYXlzLCB3ZSB3aWxsIGRlZmluZSB0aGVybWFsIHN0cmVzcyBhcyBhbnkgdGltZSB3aGVuIG1heGltdW0gZGFpbHkgd2F0ZXIgdGVtcGVyYXR1cmUgaXMgd2l0aGluIDLCsEMgb2YgY29wZXBvZCBDVG1heCBvciBoaWdoZXIuIFdlIHdpbGwgdXNlIHRocmVlIGRpZmZlcmVudCBzY2VuYXJpb3M6IDEpIHRoZSBhdmVyYWdlIENUbWF4IGZvciBlYWNoIHNwZWNpZXMsIDIpIENUbWF4IHByZWRpY3RlZCB1c2luZyBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlcywgYW5kIDMpIGZvciBzcGVjaWVzIHRoYXQgaGF2ZSBzdWZmaWNpZW50IGRhdGEsIENUbWF4IHByZWRpY3RlZCB1c2luZyB3aGljaGV2ZXIgZW52aXJvbm1lbnRhbCBmYWN0b3IgaXMgdGhlIHN0cm9uZ2VzdCBjYW5kaWRhdGUgZm9yIGRyaXZpbmcgYWNjbGltYXRpb24uIEluIGFsbCBjYXNlcywgZGF0YSBpcyBmaWx0ZXJlZCB0byBqdXN0IHRoZXJtYWwgbGltaXRzIG9mIGFkdWx0IGZlbWFsZXMuIAoKIyMjIFNjZW5hcmlvIDEKYGBge3J9Cm1lYW5fY3RtYXggPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIHN1bW1hcml6ZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSkgJT4lIAogIGFycmFuZ2UobWVhbl9jdG1heCkKCmtuaXRyOjprYWJsZShtZWFuX2N0bWF4KQpgYGAKCmBgYHtyfQojICMgQ29uc3RydWN0cyB0aGUgVVJMIGZvciB0aGUgZnVsbCB0ZW1wZXJhdHVyZSBkYXRhIHNldDsgUlVOIFRISVMgT05DRQojIGhpbmRfdXJsID0gY29uc3RydWN0TldJU1VSTChzaXRlTnVtYmVycyA9IHNpdGVOdW1iZXIsIHBhcmFtZXRlckNkID0gcGFyYW1ldGVyQ2QsIHNlcnZpY2UgPSAidXYiKQojIAojIGhpbmRfdGVtcF9kYXRhID0gaW1wb3J0V2F0ZXJNTDEoaGluZF91cmwsIGFzRGF0ZVRpbWUgPSBUKSAlPiUKIyAgIG11dGF0ZSgiZGF0ZSIgPSBhcy5EYXRlKGRhdGVUaW1lKSkgJT4lCiMgICBzZWxlY3QoZGF0ZSwgInRlbXAiID0gWF8wMDAxMF8wMDAwMCkKIyAKIyB3cml0ZS50YWJsZSh4ID0gaGluZF90ZW1wX2RhdGEsIGZpbGUgPSAiaGluZGNhc3RfdGVtcHMuY3N2Iiwgcm93Lm5hbWVzID0gRiwgc2VwID0gIiwiKQpgYGAKCmBgYHtyfQojIGdncGxvdChoaW5kX3RlbXBfZGF0YSwgYWVzKHggPSBkYXRlLCB5ID0gdGVtcCkpICsgCiMgICBnZW9tX2xpbmUobGluZXdpZHRoID0gMC4xKSArIAojICAgbGFicyh4ID0gIkRhdGUiLCAKIyAgICAgICAgeSA9ICJXYXRlciBUZW1wZXJhdHVyZSAowrBDKSIpICsKIyAgIHRoZW1lX21hdHQoKQpgYGAKCkluIHRoZSBzaW1wbGVzdCBzY2VuYXJpbywgc3BlY2llcyB0aGVybWFsIGxpbWl0cyBhcmUgc3RhdGljIHRocm91Z2ggdGltZSwgcmVwcmVzZW50ZWQgYnkgdGhlIGF2ZXJhZ2UgQ1RtYXggb2YgYWR1bHQgZmVtYWxlIGNvcGVwb2RzLiBJbiB0aGlzIHNjZW5hcmlvLCBvbmx5IHRocmVlIG9mIHRoZSBzZXZlbiBvYnNlcnZlZCBzcGVjaWVzIGFyZSBleHBvc2VkIHRvIHRoZXJtYWwgc3RyZXNzICh0ZW1wZXJhdHVyZXMgd2l0aGluIDXCsEMgb2YgQ1RtYXgpLiBUZW1wZXJhdHVyZXMgYXBwcm9hY2hlZCB0aGUgdGhlcm1hbCBsaW1pdCBvZiAqTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyogb24gYSBoYW5kZnVsIG9mIGRheXMuIEJ5IGNvbnRyYXN0LCAqU2VuZWNlbGxhIGNhbGFub2lkZXMqIGFuZCAqTGltbm9jYWxhbnVzIG1hY3J1cnVzKiB3ZXJlIGJvdGggZXhwb3NlZCB0byBzdWJzdGFudGlhbCB0aGVybWFsIHN0cmVzcyB0aHJvdWdob3V0IGEgbGFyZ2UgcG9ydGlvbiBvZiB0aGUgeWVhciwgbGlrZWx5IGV4cGxhaW5pbmcgd2h5IHRoZXNlIHNwZWNpZXMgYXJlIGFic2VudCBmcm9tIHRoZSBjb21tdW5pdHkgZm9yIHRoZSBzdW1tZXIgYW5kIGZhbGwgcGVyaW9kcy4gCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KaGluZDFfZGF0YSA9IGhpbmRfdGVtcF9kYXRhICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXplKCJkYWlseV9tYXgiID0gbWF4KHRlbXApLAogICAgICAgICAgICAiZGFpbHlfbWVhbiIgPSBtZWFuKHRlbXApLCkgJT4lIAogIGJpbmRfY29scyhwaXZvdF93aWRlcihtZWFuX2N0bWF4LCBuYW1lc19mcm9tID0gc3BfbmFtZSwgdmFsdWVzX2Zyb20gPSBtZWFuX2N0bWF4KSkgJT4lICAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUsIC1kYWlseV9tYXgsIC1kYWlseV9tZWFuKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAic3BlY2llcyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAibWVhbl9jdG1heCIpICU+JSAgCiAgbXV0YXRlKGxpbV9kaWZmID0gbWVhbl9jdG1heCAtIGRhaWx5X21heCkgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSwKICAgICAgICAgIm1ldGhvZCIgPSAiTm9fYWNjbGltYXRpb24iKQoKaGluZF9kYWlseV90ZW1wX2RhdGEgPSBoaW5kX3RlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wKQoKI3RhYmxlKGhpbmQxX2RhdGEkc3BlY2llcykKCmhpbmQxX2RhdGEgJT4lIAogIGZpbHRlcihsaW1fZGlmZiA8PSA1KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGRveSwgeSA9IGxpbV9kaWZmLCBjb2xvdXIgPSBzcGVjaWVzKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGdlb21fc21vb3RoKHNlID0gRikgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlIFxuKMKwQyBBYm92ZSBEYWlseSBNYXgpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCiMjIyBTY2VuYXJpbyAyCkluIHRoZSBzZWNvbmQgc2NlbmFyaW8sIHRoZXJtYWwgbGltaXRzIHZhcnkgd2l0aGluIGFuZCBiZXR3ZWVuIHNwZWNpZXMuIEEgc2ltcGxlIG1vZGVsIGlzIHVzZWQgdG8gcHJlZGljdCBzcGVjaWVzIHRoZXJtYWwgbGltaXRzIGJhc2VkIG9uIG1lYW4gZGFpbHkgdGVtcGVyYXR1cmUgKENUbWF4IGFzIGEgZnVuY3Rpb24gb2Ygc3BlY2llcyBhbmQgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYnV0IHdpdGhvdXQgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlc2UgdHdvIGZhY3RvcnMpLiBUaGVzZSBwcmVkaWN0ZWQgdGhlcm1hbCBsaW1pdHMgYXJlIHRoZW4gY29tcGFyZWQgYWdhaW5zdCB0aGUgbWF4aW11bSBkYWlseSB0ZW1wZXJhdHVyZSB0byBlc3RpbWF0ZSB0aGVybWFsIHN0cmVzcywgYXMgaW4gU2NlbmFyaW8gMS4gSW5jbHVkaW5nIHRoaXMgc2ltcGxlIGZvcm0gb2YgYWNjbGltYXRpb24gaW4gdGhlIG1vZGVsIHJlZHVjZWQgdGhlIGRlZ3JlZSBvZiB0aGVybWFsIHN0cmVzcyBmb3IgZWFjaCBzcGVjaWVzLCBlbGltaW5hdGluZyBpdCBlbnRpcmVseSBmb3IgKkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMqLiBOb3RlIHRoYXQgdGhlIG1hZ25pdHVkZSBvZiB0aGUgcHJlZGljdGVkIHN0cmVzcyBpcyAgbG93IGVub3VnaCB0aGF0IHJlbW92aW5nIHRoZSA1wrBDIGJ1ZmZlciBhcm91bmQgdGhlIHByZWRpY3RlZCB0aGVybWFsIGxpbWl0cyB3b3VsZCBhY3R1YWxseSBsaW1pdCBwcmVkaWN0ZWQgdGhlcm1hbCBzdHJlc3MgdG8ganVzdCBhIGZldyBkYXlzIGZvciAqU2VuZWNlbGxhIGNhbGFub2lkZXMqLiAKCmBgYHtyIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEwfQpoaW5kY2FzdF9tb2RlbDEgPSBsbShkYXRhID0gZmlsdGVyKGZ1bGxfZGF0YSwgc2V4ID09ICJmZW1hbGUiKSwKICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKyBzcF9uYW1lKQoKaGluZDJfZGF0YSA9IGhpbmRfdGVtcF9kYXRhICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXplKCJjb2xsZWN0aW9uX3RlbXAiID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgImRhaWx5X21heCIgPSBtYXgodGVtcCkpICU+JSAKICBiaW5kX2NvbHMoCiAgICBwaXZvdF93aWRlcihtZWFuX2N0bWF4LCAKICAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBzcF9uYW1lLCAKICAgICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbWVhbl9jdG1heCkpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUsIC1kYWlseV9tYXgsIC1jb2xsZWN0aW9uX3RlbXApLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzcF9uYW1lIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJtZWFuX2N0bWF4IikgJT4lIAogIHNlbGVjdCgtbWVhbl9jdG1heCkgJT4lIAogIG11dGF0ZSgicHJlZF9jdG1heCIgPSBwcmVkaWN0LmxtIChoaW5kY2FzdF9tb2RlbDEsIG5ld2RhdGEgPSAuKSkgJT4lIAogIHNlbGVjdChkYXRlLCAiZGFpbHlfbWVhbiIgPSBjb2xsZWN0aW9uX3RlbXAsIGRhaWx5X21heCwgInNwZWNpZXMiID0gc3BfbmFtZSwgcHJlZF9jdG1heCkgJT4lIAogIG11dGF0ZShsaW1fZGlmZiA9IHByZWRfY3RtYXggLSBkYWlseV9tYXgpICU+JSAKICAjZmlsdGVyKGxpbV9kaWZmIDw9IDApICU+JSAgCiAgbXV0YXRlKGRveSA9IHlkYXkoZGF0ZSksCiAgICAgICAgICJtZXRob2QiID0gIkNvbnN0YW50X2FjY2xpbWF0aW9uIikKCiMgZ2dwbG90KGhpbmQyX2RhdGEsIGFlcyh4ID0gZGFpbHlfbWVhbiwgeSA9IHByZWRfY3RtYXgsIGNvbG91ciA9IHNwZWNpZXMpKSArCiMgICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSAKCiMgdGFibGUoaGluZDJfZGF0YSRzcGVjaWVzKQpoaW5kMl9kYXRhICU+JSAgCiAgZmlsdGVyKGxpbV9kaWZmIDw9IDUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IHNwZWNpZXMpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCAKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZ2VvbV9zbW9vdGgoKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgWWVhciIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgV2FybWluZyBUb2xlcmFuY2UgXG4owrBDIEFib3ZlIERhaWx5IE1heCkiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKIyMjIFNjZW5hcmlvIDMKVGhlIGZpbmFsIHNjZW5hcmlvIGFsbG93cyB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYWJsZSB1c2VkIHRvIHByZWRpY3QgQ1RtYXggdG8gdmFyeSBiZXR3ZWVuIHNwZWNpZXMuIEZvciBzcGVjaWVzIG9ic2VydmVkIGluIGZld2VyIHRoYW4gNSBjb2xsZWN0aW9ucywgd2UgdXNlIHRoZSBzYW1lIGFwcHJvYWNoIGFzIGluIFNjZW5hcmlvIDIuIEZvciBzcGVjaWVzIG9ic2VydmVkIGluIG1vcmUgdGhhbiA1IGNvbGxlY3Rpb25zLCBob3dldmVyLCB0aGUgZmFjdG9yIHdpdGggdGhlIHN0cm9uZ2VzdCBjb3JyZWxhdGlvbiB3aXRoIENUbWF4IGlzIHVzZWQgdG8gcHJlZGljdCB0aGVybWFsIGxpbWl0cy4gVGhlc2UgZmFjdG9ycyBhcmUgaW5jbHVkZWQgYmVsb3cuCgpgYGB7cn0KaGluZF9wcmVkcyA9IGNvcnJfdmFscyAlPiUgIAogIGZpbHRlcihzaWcgPT0gIlNpZy4iKSAlPiUgCiAgZHJvcF9uYShjb3JyZWxhdGlvbikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JQogIGFycmFuZ2UoZGVzYyhjb3JyZWxhdGlvbikpICU+JSAKICBzbGljZV9oZWFkKG4gPSAxKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJQcmVkaWN0b3IiID0gcGFyYW1ldGVyLCAiRHVyYXRpb24iID0gZHVyYXRpb24sICJDb3JyZWxhdGlvbiIgPSBjb3JyZWxhdGlvbiwgIlAtVmFsdWUiID0gcC52YWx1ZSkKCmtuaXRyOjprYWJsZShoaW5kX3ByZWRzLCBhbGlnbiA9ICJjIikKYGBgCgpgYGB7cn0KaGluZDNfZGF0YSA9IGhpbmQyX2RhdGEgJT4lICMgQ29udGFpbnMgZGF0YSBmb3Igc3BlY2llcyB0aGF0IHdvbid0IGNoYW5nZSBmcm9tIHNjZW5hcmlvIDIKICBmaWx0ZXIoIShzcGVjaWVzICVpbiUgY29ycl92YWxzJHNwX25hbWUpKQoKcHJlZHNfdG9fcHVsbCA9IGhpbmRfcHJlZHMgJT4lICAKICBzZWxlY3QoU3BlY2llcywgUHJlZGljdG9yLCBEdXJhdGlvbikgCgpmb3IoaSBpbiAxOmxlbmd0aChwcmVkc190b19wdWxsJFNwZWNpZXMpKXsKICAKICBpZihwcmVkc190b19wdWxsJER1cmF0aW9uW2ldID09ICJwcmlvciIpeyAjVGhlIHByaW9yIGRheSB0ZW1wZXJhdHVyZSBtZXRyaWNzIHNob3VsZCBiZSB1c2VkCiAgICBkdXJhdGlvbiA9IE5BCiAgICAKICAgIHByZWRpY3RvcnMgPSBoaW5kX2RhaWx5X3RlbXBfZGF0YSAlPiUgCiAgICAgIG11dGF0ZShkYXRlID0gZGF0ZSArIDEpIAogICAgCiAgICBwYXJhbWV0ZXIgPSBwcmVkc190b19wdWxsJFByZWRpY3RvcltpXQogICAgCiAgICBtb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JQogICAgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSkgJT4lIAogICAgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgICAgIG11dGF0ZShjb2xsZWN0aW9uX2RhdGUgPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICAgICAgaW5uZXJfam9pbihwcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lICAKICAgICAgc2VsZWN0KGN0bWF4LCBjb250YWlucyhwYXJhbWV0ZXIpKQogICAgCiAgICBpZihkaW0obW9kZWxfZGF0YSlbMl0gPT0gMil7CiAgICAgIGhpbmQubW9kZWwgPSBsbShkYXRhID0gbW9kZWxfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICBjdG1heCB+IC4pCiAgICAgIAogICAgICBzcF9kYXRhID0gcHJlZGljdG9ycyAlPiUgCiAgICAgICAgc2VsZWN0KGRhdGUsIGNvbnRhaW5zKHBhcmFtZXRlcikpICU+JSAKICAgICAgICBtdXRhdGUocHJlZF9jdG1heCA9IHByZWRpY3QoaGluZC5tb2RlbCwgbmV3ZGF0YSA9IC4pKSAlPiUgIAogICAgICAgIHNlbGVjdChkYXRlLCBwcmVkX2N0bWF4KSAlPiUgCiAgICAgICAgaW5uZXJfam9pbihoaW5kX2RhaWx5X3RlbXBfZGF0YSwgYnkgPSBjKCJkYXRlIikpICU+JSAKICAgICAgICBtdXRhdGUoInNwZWNpZXMiID0gcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldLAogICAgICAgICAgICAgICAiZG95IiA9IHlkYXkoZGF0ZSksCiAgICAgICAgICAgICAgIGxpbV9kaWZmID0gcHJlZF9jdG1heCAtIG1heF90ZW1wKSAlPiUgCiAgICAgICAgc2VsZWN0KGRhdGUsIGRhaWx5X21lYW4gPSBtZWFuX3RlbXAsIGRhaWx5X21heCA9IG1heF90ZW1wLCBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgZG95KQogICAgICAKICAgICAgaGluZDNfZGF0YSA9IGJpbmRfcm93cyhoaW5kM19kYXRhLCBzcF9kYXRhKQogICAgfWVsc2V7CiAgICAgIHByaW50KCJUb28gbWFueSBjb2x1bW5zIHNlbGVjdGVkIikKICAgIH0KICAgIAogICAgCiAgfWVsc2V7CiAgICBkdXJhdGlvbiA9IGFzLm51bWVyaWMocHJlZHNfdG9fcHVsbCREdXJhdGlvbltpXSkKICB9CiAgCiAgaWYocHJlZHNfdG9fcHVsbCREdXJhdGlvbltpXSAhPSAicHJpb3IiICYgaXMubmEoZHVyYXRpb24pKXsgI0RhaWx5IHRlbXBlcmF0dXJlcyBzaG91bGQgYmUgdXNlZCwgYXMgaW4gU2NlbmFyaW8gMgogICAgc3BfZGF0YSA9IGhpbmQyX2RhdGEgJT4lIAogICAgICBmaWx0ZXIoc3BlY2llcyA9PSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0pCiAgICAKICAgIGhpbmQzX2RhdGEgPSBiaW5kX3Jvd3MoaGluZDNfZGF0YSwgc3BfZGF0YSkKICB9CiAgCiAgaWYoaXMubnVtZXJpYyhkdXJhdGlvbikpewogICAgI05laXRoZXIgdGhlIHByaW9yIGRheSBub3IgZGF5IG9mIG1ldHJpY3Mgc2hvdWxkIGJlIHVzZWQ7IHVzZSBkdXJhdGlvbiBhcyBuX2RheXMKICAgIAogICAgcHJlZGljdG9ycyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGhpbmRfZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IGhpbmRfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSBkdXJhdGlvbikKICAgIAogICAgcGFyYW1ldGVyID0gcHJlZHNfdG9fcHVsbCRQcmVkaWN0b3JbaV0KICAgIAogICAgbW9kZWxfZGF0YSA9IGZ1bGxfZGF0YSAlPiUKICAgICAgZmlsdGVyKHNwX25hbWUgJWluJSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0pICU+JSAKICAgICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogICAgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgICAgIGlubmVyX2pvaW4ocHJlZGljdG9ycywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAgCiAgICAgIHNlbGVjdChjdG1heCwgY29udGFpbnMocGFzdGUoImRheV8iLCBwYXJhbWV0ZXIsIHNlcCA9ICIiKSkpCiAgICAKICAgIGlmKGRpbShtb2RlbF9kYXRhKVsyXSA9PSAyKXsKICAgICAgaGluZC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gLikKICAgICAgCiAgICAgIHNwX2RhdGEgPSBwcmVkaWN0b3JzICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgY29udGFpbnMocGFyYW1ldGVyKSkgJT4lIAogICAgICAgIG11dGF0ZShwcmVkX2N0bWF4ID0gcHJlZGljdChoaW5kLm1vZGVsLCBuZXdkYXRhID0gLikpICU+JSAgCiAgICAgICAgc2VsZWN0KGRhdGUsIHByZWRfY3RtYXgpICU+JSAKICAgICAgICBpbm5lcl9qb2luKGhpbmRfZGFpbHlfdGVtcF9kYXRhLCBieSA9IGMoImRhdGUiKSkgJT4lIAogICAgICAgIG11dGF0ZSgic3BlY2llcyIgPSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0sCiAgICAgICAgICAgICAgICJkb3kiID0geWRheShkYXRlKSwKICAgICAgICAgICAgICAgbGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gbWF4X3RlbXApICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgZGFpbHlfbWVhbiA9IG1lYW5fdGVtcCwgZGFpbHlfbWF4ID0gbWF4X3RlbXAsIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBkb3kpCiAgICAgIAogICAgICBoaW5kM19kYXRhID0gYmluZF9yb3dzKGhpbmQzX2RhdGEsIHNwX2RhdGEpCiAgICAgIAogICAgfWVsc2V7CiAgICAgIHByaW50KCJUb28gbWFueSBjb2x1bW5zIHNlbGVjdGVkIikKICAgIH0KICAgIAogIH0KfQoKaGluZDNfZGF0YSA9IGhpbmQzX2RhdGEgJT4lIAogIG11dGF0ZSgibWV0aG9kIiA9ICJWYXJpYWJsZV9hY2NsaW1hdGlvbiIpCmBgYAoKVGhpcyB0aGlyZCBhcHByb2FjaCBkaWQgbm90IGFmZmVjdCB0aGUgcHJlZGljdGVkIHBhdHRlcm5zIGluICpMaW1ub2NhbGFudXMqIG9yICpTZW5lY2VsbGEqIChuZWl0aGVyIHNwZWNpZXMgaGFzIGJlZW4gb2JzZXJ2ZWQgaW4gZW5vdWdoIGNvbGxlY3Rpb25zIHRvIGVzdGltYXRlIHRoZSBlZmZlY3RzIG9mIGRpZmZlcmVudCBlbnZpcm9ubWVudGFsIGZhY3RvcnMpLiBDaGFuZ2luZyB0aGUgYWNjbGltYXRpb24gYXBwcm9hY2ggZGlkIGFmZmVjdCBwYXR0ZXJucyBpbiB0aGVybWFsIGxpbWl0cyBpbiB0aGUgb3RoZXIgc3BlY2llcyB0aG91Z2guIFRoZSBmaWd1cmUgYmVsb3cgc2hvd3MgaG93IHByZWRpY3RlZCB3YXJtaW5nIHRvbGVyYW5jZSB2YXJpZXMgb3ZlciB0aGUgeWVhciBpbiB0aGUgc2V2ZW4gc3BlY2llcywgYmFzZWQgb24gdGhlIHRocmVlIGRpZmZlcmVudCBwcmVkaWN0aW9uIG1ldGhvZHMuIEluIGdlbmVyYWwsIGNvbnN0YW50IHRoZXJtYWwgbGltaXRzICh0aGUgJ25vIGFjY2xpbWF0aW9uJyBtZXRob2QpIHJlc3VsdGVkIGluIGxhcmdlciB3YXJtaW5nIHRvbGVyYW5jZSBkdXJpbmcgdGhlIHdpbnRlciBhbmQgbG93ZXIgd2FybWluZyB0b2xlcmFuY2UgZHVyaW5nIHRoZSBzdW1tZXIsIGFsdGhvdWdoIHRoaXMgZWZmZWN0IHdhcyBzbWFsbCBpbiBtb3N0IHNwZWNpZXMuICAgICAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMH0Kc3ludGhlc2lzID0gYmluZF9yb3dzKAogIHNlbGVjdChoaW5kMV9kYXRhLCBkYXRlLCBkb3ksIGRhaWx5X21lYW4sIGRhaWx5X21heCwgc3BlY2llcywgInByZWRfY3RtYXgiID0gbWVhbl9jdG1heCwgbGltX2RpZmYsIG1ldGhvZCksCiAgc2VsZWN0KGhpbmQyX2RhdGEsIGRhdGUsIGRveSwgZGFpbHlfbWVhbiwgZGFpbHlfbWF4LCAgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIG1ldGhvZCksCiAgc2VsZWN0KGhpbmQzX2RhdGEsIGRhdGUsIGRveSwgZGFpbHlfbWVhbiwgZGFpbHlfbWF4LCAgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIG1ldGhvZCkpICU+JSAKICBtdXRhdGUobWV0aG9kID0gZmN0X3JlbGV2ZWwobWV0aG9kLCAiTm9fYWNjbGltYXRpb24iLCAiQ29uc3RhbnRfYWNjbGltYXRpb24iLCAiVmFyaWFibGVfYWNjbGltYXRpb24iKSkKCmNsaW1hdG9sb2d5ID0gc3ludGhlc2lzICU+JSAKICBncm91cF9ieShzcGVjaWVzLCBkb3ksIG1ldGhvZCkgJT4lICAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1pbl9kaWZmIiA9IG1pbihsaW1fZGlmZiksCiAgICAgICAgICAgICJtYXhfZGlmZiIgPSBtYXgobGltX2RpZmYpKSAlPiUgCiAgbXV0YXRlKG1ldGhvZCA9IGZjdF9yZWxldmVsKG1ldGhvZCwgIk5vX2FjY2xpbWF0aW9uIiwgIkNvbnN0YW50X2FjY2xpbWF0aW9uIiwgIlZhcmlhYmxlX2FjY2xpbWF0aW9uIikpCgphY2NfZWZmZWN0cyA9IHN5bnRoZXNpcyAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoZGF0ZSwgc3BlY2llcywgZG95KSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IG1ldGhvZCwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBsaW1fZGlmZikgJT4lICAKICBtdXRhdGUoImNvbnN0X2FjY19lZmZlY3QiID0gQ29uc3RhbnRfYWNjbGltYXRpb24gLSBOb19hY2NsaW1hdGlvbiwKICAgICAgICAgInZhcl9hY2NfZWZmZWN0IiA9IFZhcmlhYmxlX2FjY2xpbWF0aW9uIC0gTm9fYWNjbGltYXRpb24pCgpnZ3Bsb3Qoc3ludGhlc2lzLCBhZXMoeCA9IGRveSwgeSA9IGxpbV9kaWZmLCBjb2xvdXIgPSBtZXRob2QpKSArIAogIGZhY2V0X3dyYXAoc3BlY2llc34uKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjEpICsgCiAgbGFicyh4ID0gIkRheSBvZiBZZWFyIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCBXYXJtaW5nIFRvbGVyYW5jZSAowrBDIEFib3ZlIERhaWx5IE1heCkiKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxOCkgKyAKICB0aGVtZShzdHJpcC50ZXh0LngudG9wID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGfQp5ZWFybHlfc3VtbWFyeSA9IHN5bnRoZXNpcyAlPiUgIAogIG11dGF0ZSgieWVhciIgPSB5ZWFyKGRhdGUpKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2llcywgeWVhciwgbWV0aG9kKSAlPiUgCiAgc3VtbWFyaXNlKCJtaW5fd3QiID0gbWluKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1heF93dCIgPSBtYXgobGltX2RpZmYpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG1pbl93dCwgbWF4X3d0KSwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIm1ldHJpYyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAid3QiKQoKZ2dwbG90KHllYXJseV9zdW1tYXJ5LCBhZXMoeCA9IG1ldGhvZCwgeSA9IHd0LCBjb2xvdXIgPSBtZXRyaWMpKSArIAogIGZhY2V0X3dyYXAoLn5zcGVjaWVzKSArIAogIGdlb21fcG9pbnQoKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCmBgYAoK